spring单例bean字段未填充

Gna*_*raz 2 java spring

我需要一个服务(单身适合)和一些内部字段,比如挂起的线程列表(是的,所有内容都写成线程安全的)问题是如果我@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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

Tom*_*icz 12

你好奇还是有一些真正的问题?不过这里有一个解释.

当使用CGLIB代理类时,Spring将创建一个类似于的子类myService$EnhancerByCGLIB.此增强类将覆盖一些(如果不是全部)业务方法,以应用实际代码的横切关注点.

这真是一个惊喜.这个额外的子类不会调用super基类的方法.相反,它创建了第二个实例myService并委托给它.这意味着您现在有两个对象:您的真实对象和指向(包装)它的CGLIB增强对象.

增强类只是一个虚拟代理.它仍然具有与基类相同的字段(从中继承)但不使用它们.当你调用addToList()myService$EnhancerByCGLIB对象将首先应用一些AOP逻辑,调用addToList()myService(它包),并应用在返回剩余AOP逻辑.myService$EnhancerByCGLIB.list永远不会触及这个领域.

为什么Spring不能使用相同的类并通过委托super?我想简单一点:首先创建" 原始 "bean然后在后处理期间应用AOP代理.