Java 如何从组件注入ApplicationContext?

Java 如何从组件注入ApplicationContext?,java,spring-boot,Java,Spring Boot,我想在MyComponent类中使用ApplicationContext实例。当我尝试自动连线时,当Spring在启动时初始化我的组件时,我得到空指针异常 有没有办法在MyComponent类中自动连接ApplicationContext @SpringBootApplication public class SampleApplication implements CommandLineRunner { @Autowired MyComponent myComponent;

我想在MyComponent类中使用ApplicationContext实例。当我尝试自动连线时,当Spring在启动时初始化我的组件时,我得到空指针异常

有没有办法在MyComponent类中自动连接ApplicationContext

@SpringBootApplication
public class SampleApplication implements CommandLineRunner {

    @Autowired
    MyComponent myComponent;

    @Autowired
    ApplicationContext context;  //Spring autowires perfectly at this level

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

}


@Component
public class MyComponent{

    @Autowired
    ApplicationContext ctx;

    public MyComponent(){
        ctx.getBean(...) //throws null pointer
    }

}

如果要确保您的依赖项(bean)在构造函数中已初始化并准备就绪,则应使用构造函数注入,而不是字段注入:

    @Autowired
    public MyComponent(ApplicationContext ctx){
        ctx.getBean(...) // do something
    }
另一种方法是使用如下方法:

@Component
public class MyComponent {

    @Autowired
    ApplicationContext ctx;

    public MyComponent(){

    }

    @PostConstruct
    public void init() {
        ctx.getBean(...); // do something
    }

}

因为spring需要首先创建bean(
MyComponent
),然后设置字段的值,所以在构造函数中,字段的值是
null

,如果要确保依赖项(bean)在构造函数中已初始化并准备就绪,则应该使用构造函数注入,非现场注入:

    @Autowired
    public MyComponent(ApplicationContext ctx){
        ctx.getBean(...) // do something
    }
另一种方法是使用如下方法:

@Component
public class MyComponent {

    @Autowired
    ApplicationContext ctx;

    public MyComponent(){

    }

    @PostConstruct
    public void init() {
        ctx.getBean(...); // do something
    }

}

您得到了
NPE
,因为spring需要首先创建bean(
MyComponent
),然后设置字段的值,因此在构造函数中,字段的值是
null

问题是
MyComponent
构造函数是在spring autowires
ApplicationContext
之前调用的。 这里有两种方法:

•将依赖项注入构造函数():

@组件
公共类MyComponent{
私有最终应用上下文ctx;
@自动连线
公共MyComponent(ApplicationContext ctx){
this.ctx=ctx;
ctx.getBean(…);
}
}
•或通过现场注入(更糟糕的方式)注入,并使用
@PostConstruct
生命周期注释:

@组件
公共类MyComponent{
@自动连线
私有应用程序上下文ctx;//不是最终版本
@施工后
私有void init(){
ctx.getBean(…);
}
}
它可能不太安全,但我认为它提供了更可读的代码


哦,这是我个人使用的方式,和。 这使得几乎没有样板代码,除非您确实需要在构建时执行某些操作或具有一些不可自动连接的字段:D

@组件
@AllArgsConstructor(onConstructor_uz=@Autowired)
公共类MyComponent{
私有最终应用上下文ctx;
@施工后
私有void init(){
ctx.getBean(…);
}
}

问题是在Spring autowires
ApplicationContext
之前调用了
MyComponent
构造函数。 这里有两种方法:

•将依赖项注入构造函数():

@组件
公共类MyComponent{
私有最终应用上下文ctx;
@自动连线
公共MyComponent(ApplicationContext ctx){
this.ctx=ctx;
ctx.getBean(…);
}
}
•或通过现场注入(更糟糕的方式)注入,并使用
@PostConstruct
生命周期注释:

@组件
公共类MyComponent{
@自动连线
私有应用程序上下文ctx;//不是最终版本
@施工后
私有void init(){
ctx.getBean(…);
}
}
它可能不太安全,但我认为它提供了更可读的代码


哦,这是我个人使用的方式,和。 这使得几乎没有样板代码,除非您确实需要在构建时执行某些操作或具有一些不可自动连接的字段:D

@组件
@AllArgsConstructor(onConstructor_uz=@Autowired)
公共类MyComponent{
私有最终应用上下文ctx;
@施工后
私有void init(){
ctx.getBean(…);
}
}

您只需实现接口
ApplicationContextAware
即可检索对应用程序上下文的引用。的可能重复项的可能重复您只需实现接口
ApplicationContextAware
即可检索对应用程序上下文的引用。的可能重复项的可能重复项哦,我慢了19分钟。”啊,我慢了19分钟。”D