弹簧自注射

我用Spring 3.x尝试了以下代码,但失败了,它应该根据我之前问过的一个问题的答案 - 我可以使用Spring注入相同的类吗?BeanNotFoundException

@Service
public class UserService implements Service{
    @Autowired
    private Service self;
}

由于我在Java 6中尝试了这一点,我发现以下代码工作正常:

@Service(value = "someService")
public class UserService implements Service{
    @Resource(name = "someService")
    private Service self;
}

但我不明白它如何解决循环依赖关系。

编辑:
这是错误消息。OP在对其中一个答案的评论中提到了这一点:

由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有找到[com.spring.service.Service]类型的匹配bean用于依赖项:预期至少有1个bean有资格作为此依赖项的autowire候选项。Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}


答案 1

更新日期:2016 年 2 月

自自动布线将在Spring Framework 4.3中得到正式支持。可以在此 GitHub 提交中看到该实现。


您无法自己自动连接的最终原因是Spring方法的实现明确排除了这种可能性。这在此方法的以下代码摘录中可见:DefaultListableBeanFactory.findAutowireCandidates(String, Class, DependencyDescriptor)

for (String candidateName : candidateNames) {
    if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
        result.put(candidateName, getBean(candidateName));
    }
}

仅供参考:豆子的名称(即,试图自动连接自身的豆子)是。该 bean 实际上是自动连线候选项,但上述 if 条件返回 false(因为实际上等于 )。因此,您根本无法将Bean与自身自动连接(至少从Spring 3.1 M1开始)。beanNamecandidateNamebeanName

至于这在语义上是否是预期的行为,那是另一个问题。;)

我会问Juergen,看看他有什么要说的。

问候

山姆(核心弹簧提交者)

p.s. 我已经打开了一个春季JIRA问题,考虑使用@Autowired按类型支持自自动布线。请随时在这里观看或投票:https://jira.springsource.org/browse/SPR-8450


答案 2

此代码也有效:

@Service
public class UserService implements Service {

    @Autowired
    private ApplicationContext applicationContext;

    private Service self;

    @PostConstruct
    private void init() {
        self = applicationContext.getBean(UserService.class);
    }
}

我不知道为什么,但似乎Spring可以从如果创建但未初始化的情况下获取豆子。 在初始化之前工作,并且找不到相同的 Bean。因此,也许在之后和之前工作。ApplicationContext@Autowired@Resource@Autowired@PostConstruct

但我不知道,只是猜测。无论如何,好问题。


推荐