spring singleton bean字段未填充 [英] spring singleton bean fields are not populated

查看:138
本文介绍了spring singleton bean字段未填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个服务(单身适合)和一些内部字段,比如挂起的线程列表(是的,所有内容都写成线程安全的)问题是如果我 @autowire 这个bean,字段似乎是空的。调试我看到代理正确绑定到实例(字段 CGLIB $ CALLBACK_X 与填充的bean正确链接),填充字段,但它提供的字段为空。 / p>

以下几行代码概括了我在说什么。

  @Service 
public class myService {

@Autowired
private Monitor monitor;

public List getSomething(){
return monitor.getList();
}
}


@Service
公共类myStatefulService {

//此字段将填写为肯定有人在getSomething()之前调用
private list list;

公共同步列表getSomething(){
返回this.list;
}

//由自我注入此bean的其他服务调用
public synchronized void addToList(Object o){
this.list.add(o);
}
}

调试变量 monitor 在getList调用期间我得到了

  monitor =>正确类的实例
字段:
CGLIB $ BOUND => true
CGLIB $ CALLBACK_0.advised => proxyFactory(正确)
CGLIB $ CALLBACK_1.target(引用myStatefulService类的正确实例)
字段:
list => [.........](正确填充)
CGLIB $ CALLBACK_2 .....
......
......
......
list => [](将填充的列表为空)


解决方案

<你好奇或者你有一些真正的问题吗?不过这里有一个解释。



当使用CGLIB代理类时,Spring将创建一个名为 myService $ EnhancerByCGLIB 。这个增强的类将覆盖一些(如果不是全部)商业方法,以便在实际代码周围应用横切关注点。



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



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



为什么Spring不能使用相同的类和委托通过超级?我想简单来说:首先创建 raw bean,然后在后期处理过程中应用AOP代理。


I need a service (singleton fits) with some internal fields, like a list of pending threads (yes everything is written to be thread safe) the problem is that if I @autowire this bean, fields appear to be empty. Debugging I see that the proxy correctly binds to the instance (fields CGLIB$CALLBACK_X are correctly linked to the populated bean) with populated fields, but the fields it offers are empty.

The following lines of codes give a general idea of what i'm talking about.

@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);
   }
}

Debugging the variable monitor during the getList call I get

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)

解决方案

Are you curious or you have some real issue? Nevertheless here is an explanation.

When using CGLIB to proxy classes Spring will create a subclass called something like myService$EnhancerByCGLIB. This enhanced class will override some if not all of your business methods to apply cross-cutting concerns around your actual code.

Here comes the real surprise. This extra subclass does not call super methods of the base class. Instead it creates second instance of myService and delegates to it. This means you have two objects now: your real object and CGLIB enhanced object pointing to (wrapping) it.

The enhanced class is just a dummy proxy. It still has the same fields as your base class (inherited from it) but they are not used. When you call addToList() on myService$EnhancerByCGLIB object it will first apply some AOP logic, call addToList() of myService (which it wraps) and apply remaining AOP logic on return. The myService$EnhancerByCGLIB.list field is never touched.

Why can't Spring use the same class and delegate via super? I guess for simplicity: first create "raw" bean and then apply AOP proxying during post-processing.

这篇关于spring singleton bean字段未填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆