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

2020-05-23  本文已影响0人  Yellowtail

背景

最近在搭框架,需要在很多场景里获取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

思路就是

最后代码更新为

@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

上一篇下一篇

猜你喜欢

热点阅读