写在前头 : 兄弟们写代码一定要有好的规范鸭
今天写了一串代码 ,却在使用的时候报了null
Test 类已经被 AOP 代理 ,为了篇幅不写出来了
@ComponentpublicclassTest{@Value("hello")publicString name;@AutowiredpublicTarget target;}
publicstaticvoidmain(String[] args){ClassPathXmlApplicationContext context=newClassPathXmlApplicationContext("classpath:spring-aop.xml");Test bean= context.getBean("test",Test.class);System.out.println(bean.name);System.out.println(bean.target);System.out.println("=================");}
结果
我超 , 为什么G了 ,自动注入失败了吗 ?
首先 ,我们需要知道 ,自动代理的代理对象不是目标对象 ,而是目标对象的接口的实现类( JDK自动代理 )或者目标对象的子类( CGLIB自动代理 )
目标对象和代理对象都不是一个对象 ,而 Spring 中默认将代理对象加入 IOC容器 ,而不把目标对象加入容器 ,这样我们从容器中拿到的是代理对象.
@AutoWired
和@Value
的自动注入 发生在对象的初始化之后, 而代理对象的创建发生在自动注入之后 , 所以Spring 不会向代理对象的成员变量注入 Bean ,自然 ,例子中的name
和target
为null
那么怎么解决这个问题呢 ?
既然代理是基于 方法进行代理 ,无论怎么代理都还是需要调用 目标对象的方法 ,我们用方法返回成员变量不就行了吗
上手 !
@ComponentpublicclassTestimplementsTargetInterface{publicStringgetName(){returnthis.name;}publicTargetgetTarget(){return target;}@Value("hello")privateString name;@AutowiredprivateTarget target;}
publicstaticvoidmain(String[] args){ClassPathXmlApplicationContext context=newClassPathXmlApplicationContext("classpath:spring-aop.xml");Test bean= context.getBean("test",Test.class);System.out.println(bean.getName());System.out.println(bean.getTarget());System.out.println("=================");}
这下成功了捏