SpringBoot ApplicationContext常用工具类,应用上下文引用的保存


 

ApplicationContext、ApplicationContextInitializer、ApplicationListener、ApplicationContextAware 都是spring提供的,但通常都是直接使用springboot,所以直接介绍在springboot中的使用。

 

ApplicationContext工具类 | bean的获取

有时候需要通过应用上下文获取一些资源,比如获取容器中的bean实例,可以 @Autowired 注入 ApplicationContext 直接操作应用上下文,但太粗暴了,应用上下文这种核心、重量级的实例,怎么允许到处操作、使用,风险大、容易搞出问题。

通常是封装一个从上下文中获取资源的工具类,在应用启动时保存应用上下文的引用,在工具类中通过上下文的引用来进行操作。

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;

/**
 * 操作应用上下文 ApplicationContext 的工具类
 */
public class ApplicationContextUtils {

    /**
     * 应用上下文的引用
     */
    private static ApplicationContext applicationContext;

    /**
     * 设置应用上下文的引用
     */
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ApplicationContextUtils.applicationContext = applicationContext;
    }

    /**
     * 获取应用上下文的引用
     */
    public static ApplicationContext getApplicationContext() {
        return ApplicationContextUtils.applicationContext;
    }

    /**
     * 通过name获取bean
     *
     * @param name beanName
     * @return 获取到的bean
     */
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    /**
     * 通过class获取bean
     *
     * @param clazz bean的Class对象
     * @return 获取到的bean
     */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    /**
     * 通过name+class获取bean
     *
     * @param name  beanName
     * @param clazz bean的Class对象
     * @return 获取到的bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return applicationContext.getBean(name, clazz);
    }

}

并没有提供设置、更改应用上下文中资源的方法,要配置上下文应该在应用启动时就配置,应用启动后一般不允许再修改上下文的配置。

下面介绍在应用启动时保存应用上下文引用的常见方式。

 

保存应用上下文引用

介绍5种常见的方式,使用其中一种即可
 

在引导类中保存run()方法返回的应用上下文

最简单的保存方式

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //实例run()方法会返回创建的应用上下文
        ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
        ApplicationContextUtils.setApplicationContext(applicationContext);
    }

}

 

使用应用上下文初始化器 ApplicationContextInitializer

自定义的 ApplicationContextInitializer

//实现 ApplicationContextInitializer<ConfigurableApplicationContext>,重写 initialize() 方法
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        //保存应用上下文的引用
        ApplicationContextUtils.setApplicationContext(configurableApplicationContext);
    }

}

 
修改引导类的main()方法如下

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //创建spring容器
        SpringApplication application = new SpringApplication(DemoApplication.class);
        //添加应用上下文的初始化器。此时已经生成了应用上下文,应用上下文初始化器可以对应用上下文做进一步处理
        application.addInitializers(new MyApplicationContextInitializer());
        //启动容器
        application.run(args);
    }

}

 

说明

自定义的应用上下文初始化器、应用监听器都不建议用 spring.factories 方式进行配置,普通springboot项目可以用 spring.factories 方式配置初始化器、监听器,但构建在springboot基础上的springcloud有2个上下文:bootstrap、application,这2个上下文都会加载 spring.factories,从而出现重复调用初始化器、监听器的情况,尽量使用spring.factories之外的方式进行配置

 

使用应用监听器 ApplicationListener

应用上下文创建后,引用不会变化,可以监听启动过程中的一些指定事件,在回调方法中保存上下文的引用,比如

  • 应用上下文的 ContextRefreshedEvent、ContextStartedEvent 事件
  • 默认运行监听器发布的 ApplicationContextInitializedEvent、ApplicationPreparedEvent、ApplicationStartedEvent、ApplicationReadyEvent 事件

监听其中一种即可
 

@Component  //放到容器中
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        //保存应用上下文的引用
        ApplicationContextUtils.setApplicationContext(event.getApplicationContext());
    }

}

 
可以用 @Component 放到容器中,也可以在引导类中手动添加监听器,使用其中一种即可

//创建spring容器
SpringApplication application = new SpringApplication(DemoApplication.class);
//添加应用监听器
application.addListeners(new MyApplicationListener());
//启动容器
application.run(args);

 

使用应用上下文的Aware接口 ApplicationContextAware

自定义的 ApplicationContextAware

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component  //放到容器中
public class MyApplicationContextAware implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //保存应用上下文的引用
        ApplicationContextUtils.setApplicationContext(applicationContext);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值