我需要一个带有一些内部字段的服务(单例),比如待处理线程的列表(是的,所有内容都被编写为线程安全的),问题是,如果我@autowire
这个 bean 的字段似乎是空的。调试我发现代理正确绑定到实例(字段CGLIB$CALLBACK_X
正确链接到填充的 bean)并填充了字段,但它提供的字段是空的。
以下代码行给出了我正在谈论的内容的总体概念。
@Service
public class myService{
@Autowired
private Monitor monitor;
public List getSomething(){
return monitor.getList();
}
}
@Service
public class myStatefulService{
//This field will be populated for sure by someone before getSomething() is called
private List list;
public synchronized List getSomething(){
return this.list;
}
//Called by other services that self inject this bean
public synchronized void addToList(Object o){
this.list.add(o);
}
}
调试变量monitor
在 getList 调用期间我得到
monitor => instance of correct class
fields:
CGLIB$BOUND => true
CGLIB$CALLBACK_0.advised => proxyFactory (correct)
CGLIB$CALLBACK_1.target (reference to the correct instance of myStatefulService class)
fields:
list => [.........] (correctly populated)
CGLIB$CALLBACK_2 .....
......
......
......
list => [] (the list that would be populated is empty instead)
您好奇还是有一些实际问题?不过这里有一个解释。
当使用CGLIB代理类时,Spring将创建一个名为类似的子类myService$EnhancerByCGLIB
。这个增强的类将覆盖一些(如果不是全部)业务方法,以围绕实际代码应用横切关注点。
真正的惊喜来了。这个额外的子类不会调用super
基类的方法。相反,它创建了第二个实例myService
并代表出席。这意味着您现在有两个对象:您的真实对象和指向(包装)它的 CGLIB 增强对象。
增强类只是一个虚拟代理。它仍然具有与您的基类相同的字段(从它继承),但它们没有被使用。你打电话时addToList()
on myService$EnhancerByCGLIB
object 它首先会应用一些AOP逻辑,调用addToList()
of myService
(它包装)并在返回时应用剩余的 AOP 逻辑。这myService$EnhancerByCGLIB.list
领域从未被触及。
为什么 Spring 不能使用相同的类和委托super
?我想为了简单起见:首先创建“raw" bean,然后在后处理期间应用 AOP 代理。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)