• 获取ApplicationContext容器上下文对象实例


          Spring ApplicationContext 容器可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。另外,它增加了企业所需要的功能,比如,从属性文件从解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface 接口中定义。

          ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有这样的缺陷了。

    传统的获取ApplicationContext的方式有很多种,下面小编简单地介绍几种常用的方式!在获取ApplicationContext实例后,就可以调用getBean(beanName)返回Bean了。

           为了验证,假设已经构建了Spring Boot项目,在包com.eg.wiener.config中新增测试类。

    package com.eg.wiener.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Service;
    
    @Service
    public class BeanTest {
    
        @Bean
        public BeanTest getBeanObj() {
            BeanTest bean = new BeanTest();
            System.out.println("调用方法:" + bean);
            return bean;
        }
    
    }

    直接注入

        @Autowired
        private ApplicationContext ctx;
    
        @GetMapping("/getContext")
        public String getContext(){
            Object bean1 = ctx.getBean("getBeanObj");
            return String.format(" ctx 打印bean %s", bean1);
        }

          启动项目,可以找到日志:

    2020-06-27 10:50:16.879  INFO 12272 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2187 ms
    调用方法:com.eg.wiener.config.BeanTest@3c74aa0d

          说明bean已经被注入Spring容器,默认bean的名称就是其方法名。在浏览器访问函数getContext() 时,会返回bean【getBeanObj】的信息:

    ctx 打印bean com.eg.wiener.config.BeanTest@3c74aa0d

          和日志打印吧bean 信息一致,而且,代码System.out.println("调用方法:" + bean)不会再次执行。

    实现ApplicationContextAware接口

           创建一个实体类并实现ApplicationContextAware接口,重写接口内的setApplicationContext方法来完成获取ApplicationContext实例的方法,代码如下所示:

    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ApplicationContextProvider implements ApplicationContextAware {
        /**
         * 上下文对象实例
         */
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
        /**
         * 获取applicationContext
         *
         * @return
         */
        public ApplicationContext getApplicationContext() {
            return applicationContext;
        }
    
        /**
         * 通过name获取 Bean.
         *
         * @param name
         * @return
         */
        public Object getBean(String name) {
            return getApplicationContext().getBean(name);
        }
    
        /**
         * 通过class获取Bean.
         *
         * @param clazz
         * @param <T>
         * @return
         */
        public <T> T getBean(Class<T> clazz) {
            return getApplicationContext().getBean(clazz);
        }
    
        /**
         * 通过name,以及Clazz返回指定的Bean
         *
         * @param name
         * @param clazz
         * @param <T>
         * @return
         */
        public <T> T getBean(String name, Class<T> clazz) {
            return getApplicationContext().getBean(name, clazz);
        }
    }

          在拿到ApplicationContext对象实例后就可以获取Bean的注入实例对象,在ApplicationContextProvider类内简单的实现了几个方法来获取指定的Bean实例,也可以添加更多的方法来完成更多的业务逻辑。

          这里要注意ApplicationContextProvider类上的@Component注解是不可以去掉的,去掉后Spring就不会自动调用setApplicationContext方法来为我们设置上下文实例。

    我简单的创建了一个API,在以便测试,效果可以达到要求,代码如下:

        @Autowired
        private ApplicationContextProvider provider;
    
        @GetMapping("/getContextProd")
        public String getContextProd(){
            Object bean = provider.getBean("getBeanObj");
            return String.format(" ApplicationContextProvider 打印bean %s", bean);
        }

     在自定义AutoConfiguration中获取

          有时候我们需要实现自定义的Spring starter,并在自定义的AutoConfiguration中使用ApplicationContext,Spring在初始化AutoConfiguration时会自动传入ApplicationContext,这时我们就可以使用下面的方式来获取ApplicationContext:

    @Configuration
    @EnableFeignClients("com.yidian.data.interfaces.client")
    public class FeignAutoConfiguration {
    
    FeignAutoConfiguration(ApplicationContext context) {
    // 在初始化AutoConfiguration时会自动传入ApplicationContext
    doSomething(context);
    }}

     

    启动时获取ApplicationContext

          在启动Spring Boot项目时,需要调用SpringApplication.run()方法,而run()方法的返回值就是ApplicationContext,我们可以把run()方法返回的ApplicationContext对象保存下来,方便随时使用。下面使用这个返回示例获取Bean示例:

        private static ApplicationContext applicationContext;
    
        public static void main(String[] args) {
            applicationContext = SpringApplication.run(WienerApplication.class, args);
            Object bean1 = applicationContext.getBean("getBeanObj");
    
            System.out.println(String.format("打印bean1 %s", bean1));
            bean1 = applicationContext.getBean("getBeanObj");
            System.out.println(String.format("打印bean2 %s", bean1));
        }

          项目启动后,在日志中可以发现如下三条记录:

    调用方法:com.eg.wiener.config.BeanTest@3c74aa0d
    打印bean1 com.eg.wiener.config.BeanTest@3c74aa0d
    打印bean2 com.eg.wiener.config.BeanTest@3c74aa0d

    通过WebApplicationContextUtils获取

          Spring提供了一个工具类用于获取ApplicationContext对象:

    WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
    WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);

          关于以上5种获取ApplicationContext上下文对象实例的方式,大家有什么看法,欢迎留言讨论,也希望大家多多点赞,祝各位生活愉快。

     

    Reference

     

       https://www.jianshu.com/p/ef7739a01cb0

  • 相关阅读:
    获取资源文件 r.drawable中的图片转换为drawable、bitmap
    Android 启动白屏或者黑屏闪现解决
    Android应用截图方法
    史上最全的变量、作用域和内存问题
    RunLoop总结:RunLoop的应用场景(四)
    poj3436 ACM Computer Factory, 最大流,输出路径
    android开发——从相冊中选择图片不裁剪
    <html>
    poj3073
    poj 2482 Stars in Your Window (线段树扫描线)
  • 原文地址:https://www.cnblogs.com/east7/p/13199692.html
Copyright © 2020-2023  润新知