2016-12-02 125 views
1

我有一个基于Spring Data和Spring的Java项目。Java Spring Data @Autowired issue

我有一个Spring bean和Spring数据存储库自动装入它。我希望这个bean作为一个字段被注入自己。

我bean是:

@Service @Transactional public class JobService { 

    @Autowired private ChatMessagesRepository chatMessagesRepository; 
} 

但是,如果我尝试这个bean注入到自身,所有的Spring数据(我相信其他豆类)成为null,自动装配崩溃。为什么会发生?

我的配置:

.... 
<aop:aspectj-autoproxy proxy-target-class="true"/> 
    <mvc:annotation-driven/> 

    <jpa:repositories base-package="..." 
         entity-manager-factory-ref="entityManagerFactory" 
         transaction-manager-ref="transactionManager"/> 

    <context:annotation-config/> 
    <context:component-scan base-package="..."> 
     <context:exclude-filter type="annotation" 
           expression="org.springframework.context.annotation.Configuration"/> 
    </context:component-scan> 
.... 
+0

这是一个sIngleton豆 – avalon

+1

我不确定,但是,你尝试其他范围? –

+1

因为我希望JobService中的一个方法可以通过REQUIRES_NEW事务中的这个类中的其他方法调用,但是如果我只从另一个方法调用一个方法,事务将是相同的。 – avalon

回答

-2

自动装配Autowired适用于公共变量或方法

@Service @Transactional public class JobService { 

    private ChatMessagesRepository chatMessagesRepository; 

    @Autowired public void setChatMessagesRepository(ChatMessagesRepository chatMessagesRepository) { 
     this.chatMessagesRepository = chatMessagesRepository; 
    } 
} 
0

你不能一个bean注入本身,这将是一个周期。

有四种方案:

请参阅Spring Reference

这意味着对该对象引用的方法调用将是代理上的调用,因此代理将能够委托给与该特定方法调用相关的所有拦截器(通知)。然而,一旦该呼叫最终到达目标对象,在这种情况下引用SimplePojo,则将针对该引用而不是代理调用其自身可能进行的任何方法调用,例如​​或this.foo() 。这具有重要的意义。这意味着自我调用不会导致与方法调用相关的建议获得执行机会。

好的,那该怎么办?最好的方法(在这里松散地使用术语best)是重构你的代码,使得自调用不会发生。当然,这确实需要你做一些工作,但它是最好的,侵入性最小的方法。下一个方法是非常可怕的,我几乎不愿意指出它,因为它太可怕了。你可以(呛!)做这个类中完全把逻辑的Spring AOP:

public class SimplePojo implements Pojo { 

    public void foo() { 
     // this works, but... gah! 
     ((Pojo) AopContext.currentProxy()).bar(); 
    } 

    public void bar() { 
     // some logic... 
    } 
} 

这样完全将你的代码交给了Spring AOP,并且让类本身知道的事实,它正在在AOP上下文中使用,它在AOP中飞行。

[...]

最后,必须指出的是,AspectJ中没有这种自我调用的问题,因为它不是基于代理的AOP框架。