如何在普通类中获取
Spring
管理的Bean
,各种姿势,从本文中寻找。
通常,在Spring
应用程序中,当我们使用@Bean
/@Service
/@Controller
、@Component
/@Configuration
或者其它的注解将Bean
注入的Spring IOC
。然后我们可以使用@Autowired
或者@Resource
来使用由Spring IoC
来管理的Bean
。
一、从应用程序上下文中获取Bean
我们今天学习将来如何从ApplicationContext
中的Bean
。因为有些情况下我们不得不从应用程序上下文中来获取Bean
,例如在没有注入Spring
的工具类中。
1.1 在初始化时保存ApplicationContext
对象
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
这种方式适用于采用Spring
框架的独立应用程序,需要程序通过配置文件手工初始化Spring
的情况。
注意:在获取失败时抛出异常。
1.2 通过Spring
提供的工具类获取ApplicationContext
对象
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
ac2.getBean("beanId");
这种方式适合于采用Spring
框架的B/S
系统,通过ServletContext
对象获取ApplicationContext
对象,然后在通过它获取需要的类实例。获取失败时返回null
。
1.3 继承自抽象类ApplicationObjectSupport
抽象类ApplicationObjectSupport
提供getApplicationContext()
方法,可以方便的获取ApplicationContext
。
Spring
初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)
方法将ApplicationContext
对象注入。
1.4 继承自抽象类WebApplicationObjectSupport
类似上面方法,调用getWebApplicationContext()
获取WebApplicationContext
1.5 通过Spring
提供的ContextLoader
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
wac.getBean(beanID);
该方式不依赖于servlet
,不需要注入的方式。
1.6 实现接口ApplicationContextAware
(本文重点)
实现该接口的setApplicationContext(ApplicationContext context)
方法,并保存ApplicationContext
对象。Spring
初始化时,会通过该方法将ApplicationContext
对象注入。
二、Spring ApplicationContext
工具类
2.1 项目准备
新增一个
Bean
,使其被Spring IOC
管理。
SpringBean.java
@Component
public class SpringBean {
private String desc;
public String getDesc() {
return "SpringBean desc";
}
}
application.yml
demo:
value: 8888
2.2 定义一个工具类,实现 ApplicationContextAware
@Component
public final class SpringUtils implements ApplicationContextAware {
/**
* Spring应用上下文环境
*/
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.applicationContext == null) {
SpringUtils.applicationContext = applicationContext;
}
}
/**
* 获取对象,重写了bean方法
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return SpringUtils.applicationContext.getBean(clazz);
}
/**
* 同上方法
* @param name
* @return
*/
public static Object getBean(String name) {
return SpringUtils.applicationContext.getBean(name);
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
* @param name
* @return
*/
public static boolean containsBean(String name) {
return SpringUtils.applicationContext.containsBean(name);
}
/**
* 读取配置信息
* @param key
* @return
*/
public static String getProperty(String key) {
return SpringUtils.applicationContext.getEnvironment().getProperty(key);
}
}
- 通过
@Component
注解将SpringUtils.java
注入的Spring IOC
,Spring
能够为我们自动地执行setApplicationContext()
方法; - 我在该工具类封装了三个方法,主要用于获取
Bean
/判断Bean
是否存在/获取配置文件中信息。
2.3 getBean()
该方法用于获取对象,获取不到会抛异常。
- 测试
@Test
public void getBeanDemo() {
SpringBean springBean = SpringUtils.getBean(SpringBean.class);
log.info("springBean.desc:{}", springBean.getDesc());
// 如果bean 不存在
log.info("springBeanOther:{}", SpringUtils.getBean("springBeanOther"));
}
2.4 containsBean()
用来判断该
Bean
是否注入到Spring IOC
。
- 测试
@Test
public void containsBeanDemo() {
log.info("containsBean:{}", SpringUtils.containsBean("springBean"));
// 如果bean 不存在
log.info("containsBean:{}", SpringUtils.containsBean("springBeanOther"));
}
2.5 getProperty()
用来获取配置文件属性,属性不存在返回
null
。
- 测试
@Test
public void getPropertyDemo() {
String value = SpringUtils.getProperty("demo.value");
log.info("value:{}", value);
// 配置中不存在
String key = SpringUtils.getProperty("demo.key");
log.info("key:{}", key);
}
三、总结
这里仅作简单展示,如需探究更多使用方法,可以直接定义getApplicationContext()
方法,将ApplicationContext
返回,具体详见文末工具类中代码。
@Test
public void getApplicationContext() {
ApplicationContext context = SpringUtils.getApplicationContext();
log.info("context.containsBean():{}", context.containsBean("springBean"));
}
3.1 日常求赞
博主祖传秘籍 Spring Boot 葵花宝典 开源中,欢迎前来吐槽,提供线索,告诉博主接下来更新哪方面文章,共同进步!
3.2 文化交流
最新文章,欢迎关注:公众号-风尘博客;交流观点,欢迎添加:个人微信