背景
最近在搭框架,需要在很多场景里获取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
Filter
是 servlet
协议规定的,所以是 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);
}
}
网友评论