java - spring 单例 bean 字段未填充

标签 java spring

我需要一个带有一些内部字段的服务(单例匹配),比如待处理线程的列表(是的,所有内容都是线程安全的)问题是,如果我 @autowire这个bean,字段似乎是空的。调试我看到代理正确绑定(bind)到实例(字段 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()myService$EnhancerByCGLIB对象它会首先应用一些 AOP 逻辑,调用 addToList()myService (它包装)并在返回时应用剩余的 AOP 逻辑。 myService$EnhancerByCGLIB.list字段从未被触及。

为什么 Spring 不能通过 super 使用相同的类和委托(delegate)? ?我想为简单起见:首先创建“原始”bean,然后在后处理期间应用 AOP 代理。

关于java - spring 单例 bean 字段未填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11580911/

相关文章:

java - 无法部署 GoogleAppEngine 项目!

Java 使用第 3 方套接字库的好处

java - 登录后填充用户 session

java - Spring CriteriaBuilder 按名称搜索枚举

java - 当父 portlet 的 use-default-template 值为 true 时,运行时添加的 portlet 不会呈现

java - SQLiteStatement 为什么没有 SELECT 语句的方法 - 任何解决方法加上为什么没有线程安全

java - 选择排序中的交换

java - 最好处理 2 个重叠的实时更新面板?

java - 如何使用 Spring MVC 将 session 属性作为方法参数(参数)传递

java - 重新加载不包括某些 bean 的 spring bean