SpringAOP实现报错Bean named ‘userServiceImpl‘ is expected to be of type ‘.....‘

在Spring AOP实践中遇到Bean类型错误,报错表明'UserServiceImpl'实际类型为代理类型'$Proxy17'。问题源于获取Bean时要求的类型应为接口或父类。解决方案包括两种:一是通过指定接口类型获取Bean;二是直接通过接口字节码获取实现类的Bean。修改getBean方法的参数类型即可解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

在练习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, "张三");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值