Java Spring Data @Autowired问题

时间:2016-12-02 17:35:31

标签: java spring spring-data

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

我有一个Spring bean和Spring数据存储库自动加入其中。我希望这个bean作为一个字段注入自身。

我的豆是:

@Service @Transactional public class JobService {

    @Autowired private ChatMessagesRepository chatMessagesRepository;
}

但是,如果我尝试将这个bean注入其中,那么所有Spring Data(我相信其他bean)都会变成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>
....

2 个答案:

答案 0 :(得分:0)

你不能将豆子注入其自身,这将是一个循环。

有四种解决方案:

  • 将你的豆切成两个豆(最佳方法)
  • 使用AspectJ
  • 使用ApplicationContextAware
  • 将您的代码耦合到Spring
  • 使用AopContext
  • 将您的代码耦合到Spring

请参阅Spring Reference

  

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

     

好的,那么该怎么办呢?最好的方法(这里松散地使用最好的术语)是重构代码,以便不会发生自我调用。当然,这确实需要你做一些工作,但这是最好的,最少侵入性的方法。接下来的方法是绝对可怕的,我几乎要谨慎地指出它,因为它是如此可怕。你可以(扼流!)通过这样做完全将你班级中的逻辑与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框架。

答案 1 :(得分:-2)

自动连接适用于公共变量或方法

@Service @Transactional public class JobService {

    private ChatMessagesRepository chatMessagesRepository;

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