Spring Boot之前从另一个模块加载bean

时间:2018-05-13 21:09:54

标签: java spring maven spring-boot

我有两个maven模块:

api-module
commons-module

api-module 包含 com.example.api 包,commons-module包含 com.example.commons 包。

当我运行主应用 com.example.api.ApiMain 时,执行失败。 这是因为我在 commons 包中定义了Mongo Repository类。 API控制器依赖于它们,并且由于它们未在 api bean之前实例化,因此执行失败。

以下是主要的api app:

package com.example.api;

@SpringBootApplication
@ComponentScan({"com.example.commons", "com.example.api"})
public class ApiMain {
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {
        SpringApplication.run(ApiMain.class, args);
    }
}

如何在加载 com.example.api 中的bean之前确保扫描 com.example.commons 组件?

我可以在 com.example.api 中的每个bean上使用 @DependsOn annoation但是有几个类,将来还会添加几个类,它将使代码难看。

如果有办法指示spring首先从 commons-module 加载组件,就可以解决这个问题。

您可以告诉我如何执行此操作。

2 个答案:

答案 0 :(得分:0)

无论首先扫描哪个包都无关紧要,因为Spring将构建一个依赖关系图并找出实例化bean的顺序。如果您希望某些bean在其他bean之前被实例化,就像让我们说BeanA取决于BeanB一样,那么BeanA将有一个构造函数@Autowired BeanA(BeanB b)

确定实例化的顺序是Spring Dependency Injection的一个基本方面,我建议你在Spring DI上阅读更多内容,因为我不认为你正在理解控制反转的概念以及Spring DI的作用

但是听起来我觉得你有类似的东西:

public class BeanA {
    @Autowired
    BeanB b;
    public BeanA() {
        b.doSomething();
    }
}

但是b的构造函数被调用时BeanA仍为null。因为您使用BeanABeanB中执行某种实例化,所以您得到NullPointerException,而您必须拥有:BeanA(BeanB b)

答案 1 :(得分:0)

我遇到了同样的问题。我在下面的代码中使用了Rest API控制器

@RestController
@EnableOAuth2Sso
@EnableResourceServer
@SpringBootApplication
public class SpringBootWebApplication extends WebSecurityConfigurerAdapter {

    //Dependancy injection using autowire
    @Autowired
    OAuth2ClientContext oauth2ClientContext;
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }

将此代码用于呈现我的HTML页面的普通控制器

@Configuration
@EnableAutoConfiguration
@Controller
public class WelcomeController {

试试这个并告诉我这是否有效或者您仍有问题。