问题
在练习SpringAOP过程中出现如下报错
Bean named ‘userServiceImpl’ is expected to be of type ‘com.fjd.service.impl.UserServiceImpl’ but was actually of type ‘com.sun.proxy.$Proxy17’
原因
public class Test1 {
@Test
public void getBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserServiceImpl userServiceImpl = context.getBean("userServiceImpl", UserServiceImpl.class);
userServiceImpl.addUser(1, "张三");
}
}
根据报错提示,我们可以翻译为:
命名为’userServiceImpl’的Bean的类型应该是’com.service.impl .UserServiceImpl’但实际上类型是’com.sun.proxy.$Proxy17’
也就是说,实际上要求传的是代理类型,而代理类型我们知道有JDK的代理和cglib的代理,所以传入的bean字节码类型应该是接口类型或者父类类型,因为JDK的代理是面向接口的,而cglib的代理是面向父类的。
再看getBean()方法解释:
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
* safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
* required type. This means that ClassCastException can't be thrown on casting
* the result correctly, as can happen with {@link #getBean(String)}.
* <p>Translates aliases back to the corresponding canonical bean name.
* <p>Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @param requiredType type the bean must match; can be an interface or superclass
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type
* @throws BeansException if the bean could not be created
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
由上
@param requiredType type the bean must match; can be an interface or superclass
可知
要求的requiredType类型要是一个接口或一个父类
解决
只需要把传入的类型改为接口或父类字节码类型即可。
方式一:参数1写实现类(默认是类名但首字母要小写),参数二传接口字节码类型
public class Test1 {
@Test
public void getBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
userService.addUser(1, "张三");
}
}
方式二:直接传字节码,会根据接口去匹配接口下面的实现类
public class Test1 {
@Test
public void getBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//直接传接口的字节码,会根据接口去匹配接口下面的实现类
UserService userService = context.getBean(UserService.class);
userService.addUser(1, "张三");
}
}