public class app3 {
public static void main(String[] args) throws ServletException, IOException {
ApplicationContext ctx= new AnnotationConfigApplicationContext(springConfig.class);
// 获取相应的代理对象--错误代码(其中dao1是配置的bean的id)
BrandServiceImpl brandServiceImpl = (BrandServiceImpl) ctx.getBean("dao1");
brandServiceImpl.selectAll2();
// 正确代码
BrandService brandService2 = ctx.getBean(BrandService.class);
System.out.println(brandService2);
brandService2.selectAll2();
}
这里的具体的场景是:获取相应的代理对象进行测试AOP.
其中 BrandService是接口,BrandServiceImpl是相应的接口的实现类。
具体的改造的方法是,利用Aop进行的编程的时候,通过ctx.getBean("dao1");所得到的是一个代理对象,它的类型是相应的接口实现类所实现的接口的类型,也就是BrandService。所以会出现如下错误。
所以只需要把相应的类型转换成接口类型BrandService即可。
BrandService brandService3 = (BrandService) ctx.getBean("dao1");
System.out.println(brandService3);
brandService3.selectAll2();
//或者
BrandService brandService = ctx.getBean(BrandService.class);
System.out.println(brandService);
brandService.selectAll2();
详细的解释:
代理对象是通过 Spring AOP 自动生成的用于管理切面逻辑的对象。当你使用 Spring AOP 时,Spring 会根据你定义的切面和切点,动态地生成代理对象,这些代理对象包装了原始的目标对象,以便在方法调用前后插入切面逻辑。
在你的代码中,通过以下代码获取的对象就是一个代理对象:
BrandService brandService = (BrandService) ctx.getBean("dao1");
这里的 ctx.getBean("dao1")
获取了名为 "dao1" 的 bean,而根据你之前的代码,"dao1" 是一个 Spring 托管的 BrandServiceImpl
类型的 bean。然而,由于你在配置中可能使用了 Spring AOP,BrandServiceImpl
可能已经被代理了。
这意味着 brandService
这个对象实际上是 BrandServiceImpl
类型的代理对象,它会包装 BrandServiceImpl
的实例,并在方法调用前后执行与切面相关的逻辑。
因此,当你尝试将这个代理对象转换为 BrandServiceImpl
类型时,会发生类型转换异常,因为代理对象并不是直接的 BrandServiceImpl
类型,而是代理类型。
解决这个问题的方法是,将类型转换为代理对象实现的接口类型,而不是具体的实现类类型,如我之前所示。这样可以避免类型转换异常,并正确地使用代理对象。