美文网首页
Spring Boot 里面 随时随地拿到 bean 对象

Spring Boot 里面 随时随地拿到 bean 对象

作者: Yellowtail | 来源:发表于2020-05-23 10:36 被阅读0次

    背景

    最近在搭框架,需要在很多场景里获取bean, 搜了一些资料,分享出来

    0x0 bean 里取 bean

    这个是最简单的了,
    如果类型只有一个,使用 @Autowired 即可
    如果类型有多个,加一个注解@Qualifier 即可

    @Qualifier("your bean name")
    @Autowired
    

    常见的有,在 service dao
    Spring boot 的一些组件,如 拦截器也是可以的

    0x1 静态工具类

    有时候,在一些工具类里,我们希望能拿到bean对象,获取一些信息
    可以通过实现接口 ApplicationContextAware 来拿到 ApplicationContext, 保存到 静态变量里
    代码如下

    @Component
    public class SpringUtils implements ApplicationContextAware {
        private static final Logger LOGGER = LoggerFactory.getLogger(SpringUtils.class);
    
        private static ApplicationContext APP_CONTEXT;
    
        public static ApplicationContext getApplicationContext(){
            return APP_CONTEXT;
        }
    
    
        public void setApplicationContext(ApplicationContext appContext) throws BeansException {
            APP_CONTEXT = appContext;
        }
    
        /**
         * 获取容器中的Bean对象
         * @param beanId
         * @return
         */
        @SuppressWarnings("unchecked")
        public static <T>T getBean(String beanId){
            
            if(null == APP_CONTEXT) {
                return null;
            }
    
            return (T)APP_CONTEXT.getBean(beanId);
        }
    }
    

    注意到代码里有一个判空检查 if(null == APP_CONTEXT) {
    这是因为,如果静态方法在Spring IOC 容器初始化之前被调用,此时 setApplicationContext 不会被调用,工具类是拿不到 上下文ApplicationContext

    0x2 Filter

    Filterservlet 协议规定的,所以是 servlet容器负责管理的, 不归Spring
    所以在里面使用 @Autowired 主动注入会失败

    网上搜索了一下,有的使用 @Configuration@Bean 联合起来的方式生成和注入 Filter对象, 感觉有点笨拙
    搜到了一篇文章还不错,用了一下也可以
    csdn

    思路就是

    • 从 filterConfig 配置里拿到 servlet 上下文
    • 使用spring的工具类 从 servlet 上下文 拿到 web 应用的上下文 WebApplicationContext

    最后代码更新为

    @Component
    public class SpringUtils implements ApplicationContextAware {
        private static final Logger LOGGER = LoggerFactory.getLogger(SpringUtils.class);
    
        private static ApplicationContext APP_CONTEXT;
    
        public static ApplicationContext getApplicationContext(){
            return APP_CONTEXT;
        }
    
    
        public void setApplicationContext(ApplicationContext appContext) throws BeansException {
            APP_CONTEXT = appContext;
        }
    
        /**
         * 获取容器中的Bean对象
         * @param beanId
         * @return
         */
        @SuppressWarnings("unchecked")
        public static <T>T getBean(String beanId){
    
            return (T)APP_CONTEXT.getBean(beanId);
        }
    
        public static <T> T getBean(Class<T> clazz) {
            return APP_CONTEXT.getBean(clazz);
        }
    
        public static <T> T getBean(Class<T> clazz, FilterConfig filterConfig) {
            if (null == APP_CONTEXT) {
                // 从 filterConfig 配置里拿到 servlet 上下文
                ServletContext servletContext = filterConfig.getServletContext();
    
                // 使用spring的工具类 从 servlet 上下文 拿到 web 应用的上下文
                WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
                if (null == webApplicationContext) {
                    return null;
                }
    
                return webApplicationContext.getBean(clazz);
            }
    
            return APP_CONTEXT.getBean(clazz);
        }
    }
    

    参考

    csdn

    相关文章

      网友评论

          本文标题:Spring Boot 里面 随时随地拿到 bean 对象

          本文链接:https://www.haomeiwen.com/subject/ggkkahtx.html