首页 > 解决方案 > Spring如何决定初始化Bean和普通类的顺序?

问题描述

我有一个豆子如下,

 @Component 
 public class SpringContextUtil implements ApplicationContextAware { 

     private static ApplicationContext context = null; 

     @Override 
     public void setApplicationContext(ApplicationContext applicationContext) 
         throws BeansException { 
     this.context = applicationContext; 
     } 

     public static <T> T getBean(String beanName) { 
         return (T) context.getBean(beanName); 
     } 

     public static String getActiveProfile() { 
         return context.getEnvironment().getActiveProfiles()[0]; 
     } 
 } 

它被普通类使用,

public class ConfigUtil
{
    static{
        String env = SpringContextUtil.getActiveProfile();
        ...
    }

    public static getVal(String key){...}
}

如果 Spring Bean SpringContextUtil 是在普通类 ConfigUtil 之后初始化的,那就不行了。所以我想知道Spring如何决定哪个更早初始化?例如,调用 SpringContextUtil.getActiveProfile() 会触发 Spring bean 的初始化吗?还是 Spring Bean 仅被初始化但尚未注入 applicationContext,从而导致空指针异常?

标签: javaspring

解决方案


你只需要在 spring 初始化之后运行你的代码。

如果您使用的是 spring-boot,请创建新的 bean 来实现ApplicationListener<ApplicationReadyEvent>并在方法中运行您的代码onApplicationEvent

例子

@Component
public class ApplicationListenerBean implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        ConfigUtil.getVal("A");
    }
}

但是,如果您还想将其制作ConfigUtil为 spring bean,则需要摆脱静态初始化块并@PostConstruct在您的 init 方法上使用注释。

例子

@Component
@DependsOn("springContextUtil")
public class ConfigUtil {

    private String env;

    @PostConstruct
    private void init() {
        env = SpringContextUtil.getActiveProfile();
    }


    public static void getVal(String key) {
        System.out.print("Hello");
    }
}

推荐阅读