Java 未填充spring单例bean字段

Java 未填充spring单例bean字段,java,spring,Java,Spring,我需要一个带有一些内部字段的服务(singleton fits),比如一个挂起线程的列表(是的,所有内容都是为了线程安全而编写的)。问题是,如果我@autowire这个bean,字段似乎是空的。调试时,我看到代理使用填充的字段正确绑定到实例(字段CGLIB$CALLBACK\X正确链接到填充的bean),但它提供的字段是空的 下面几行代码概括了我所说的内容 @Service public class myService{ @Autowired private Monitor mon

我需要一个带有一些内部字段的服务(singleton fits),比如一个挂起线程的列表(是的,所有内容都是为了线程安全而编写的)。问题是,如果我
@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);
   }
}
在getList调用期间调试变量
monitor

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)
“在调用getSomething()之前,此字段肯定会有人填充”

有人吗?不,是春豆厂。如果不进行配置,则不会填充任何内容

并不是每个豆子都需要在春天的控制之下。听起来您希望有一个
列表
,客户端可以通过线程安全的方式向其中添加和删除项目。如果是这样,请删除
@Autowired
注释,创建一个新的
列表
,并公开要添加和删除的方法


我推荐一份新的并发收藏列表。

你是好奇还是有什么真正的问题?然而,这里有一个解释

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

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

增强的类只是一个虚拟代理。它仍然具有与基类(继承自基类)相同的字段,但未使用这些字段。当您在
myService$enhancerbyglib
对象上调用
addToList()
时,它将首先应用一些AOP逻辑,调用
myService
addToList()
(它包装了它),并在返回时应用剩余的AOP逻辑。myService$EnhancerByGlib.list字段从未被触动过


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

CGLIB将代理受保护的getter

因此,您可以:

@Autowired
private Monitor monitor;

protected Monitor getMonitor() { return monitor; }

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

getMonitor()将被代理,以便在已注入monitor的另一个实例上调用getMonitor()。

抱歉,列表中的@autowired是一个键入错误。。。。一切都在Spring控件的控制之下,“某人”是响应客户端操作的另一个服务。。。因此,客户端使用其他服务将元素添加到列表中。带有列表的服务包含逻辑,并且定期在列表上工作,因此我需要是一个单例可注入有状态bean=),是的,我提供了向列表添加元素的方法,但是当读取列表时,如果代理指向的实例已正确填充,则列表也是空的。为什么需要代理?我想说,这是一个不需要受Spring控制的对象的示例。只需实例化一个新的,然后继续。提到
super
就救了我一天!我花了几个小时试图弄清楚为什么调用我的基类而不是增强版,直到我意识到调用程序调用了一个从基类本身传递回来的对
的引用,这显然是行不通的。