Spring系列:从应用获取Bean的常用姿势

如何在普通类中获取 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);
    }
}
  1. 通过@Component注解将SpringUtils.java注入的Spring IOCSpring能够为我们自动地执行 setApplicationContext() 方法;
  2. 我在该工具类封装了三个方法,主要用于获取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"));
}

Github 示例代码

  1. SpringUtils.java
  2. SpringUtilsTest.java

3.1 日常求赞

博主祖传秘籍 Spring Boot 葵花宝典 开源中,欢迎前来吐槽,提供线索,告诉博主接下来更新哪方面文章,共同进步!

3.2 文化交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. 风尘博客-CSDN
  5. Github

最新文章,欢迎关注:公众号-风尘博客;交流观点,欢迎添加:个人微信

风尘博客个人微信号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值