简体   繁体   English

Spring @Autowire以一种奇怪的方式运行,为初始化的bean返回null

[英]Spring @Autowire is behaving in a weird way returning null for initialized bean

I have a legacy spring application, with a mix of xml and java config. 我有一个传统的Spring应用程序,混合了xml和java config。 (not my choice sorry). (对不起,我没有选择)。 The spring context is initialized from the xml config, which has a component scan instruction to scan the java configs. spring上下文是从xml配置初始化的,该配置具有扫描Java配置的组件扫描指令。

There are many java config classes, below are code snippets from 2 of them where I see a problem. 有很多Java配置类,下面是其中2个出现问题的代码段。 My @Bean DateProvider dateProvider() in ReplayConfig is initialized first, and I can see this by putting a breakpoint in the constructor. 我的@Bean DateProvider dateProvider() ReplayConfig被初始化,我可以通过在构造函数中放置一个断点来看到这一点。 And then in AnotherConfig I autowire @Autowired private DateProvider dateProvider; 然后在AnotherConfig我自动装配@Autowired private DateProvider dateProvider; After having used @Import(ReplayConfig.class) . 使用@Import(ReplayConfig.class)

All good so far, except it turns out the instance of my portfolioService has been passed a null dateProvider. 所有好为止,除了事实证明我的实例portfolioService已经通过空dateProvider。 It is frustrating to see experience this, given I can clearly see that dateProvider has been instantiated earlier. 鉴于我能清楚地看到dateProvider早已实例化,因此看到这种体验令人沮丧。

I can actually get it to work if I add to PortfolioServiceImpl 如果我添加到PortfolioServiceImpl我实际上可以使其工作

@Autowired setDateProvider(DateProvider dateProvider) 

Which I thought would remove all doubt about possibility of confusing packages or different classes with the same name or silly things like that. 我认为这将消除所有可能混淆具有相同名称或类似名称的包或不同类的可能性的疑问。

The only thing I can think of is something else is wrong. 我唯一能想到的是其他错误。 If someone can suggest any ideas it would be great. 如果有人可以提出任何想法,那就太好了。

Unfortunately I can't get away from the xml initialisation for now. 不幸的是,我暂时无法摆脱xml初始化。

More code below: 下面的更多代码:

@Import (EnvironmentConfig.class)
@Config
ReplayConfig{
   @Bean
    DateProvider dateProvider() {
        SystemDateProvider systemDateProvider = new SystemDateProvider (bean());
        return systemDateProvider;
    }
}

Then we import that and try to auto wire dateProvider 然后我们导入该文件并尝试自动连接dateProvider

 @Import(ReplayConfig.class)
    @Configuration
    public class AnotherConfig {
        @Autowired
        private DateProvider dateProvider;

        @Bean
        PortfolioService portfolioService() {
            PortfolioService  portfolioService = new PortfolioServiceImpl(dateProvider, bean(),otherBean());
            return portfolioService 
        }
    }

this is how we trigger component scan: 这是我们触发组件扫描的方式:

<!--******************************************  Scan for JavaConfig  ******************************************-->
<context:component-scan base-package="com.app.config, com.app.common.config">
         <context:exclude-filter type="regex" expression="com\.app\.a4\.systest.*"/>
         <context:exclude-filter type="regex" expression="com\.app\.common\.systest.*"/>
</context:component-scan>

And here's how we start the application, and create the context: 这是我们启动应用程序并创建上下文的方法:

public static void main(String[] args) {

        try(ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(getResourcePath())){
            context.setClassLoader(Thread.currentThread().getContextClassLoader());
        }
}

I guess instead of Autowiring dateProvider to your AnotherConfig you can try to adjust bean declaration of portfolioService to the following one: 我想,而不是自动装配的dateProviderAnotherConfig你可以尝试的bean声明调整portfolioService下列之一:

@Bean
PortfolioService portfolioService(DateProvider dateProvider) {
    PortfolioService  portfolioService = new PortfolioServiceImpl(dateProvider, bean(),otherBean());
    return portfolioService 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM