目 录CONTENT

文章目录

Spring 中获取 Bean 的八种方式

在等晚風吹
2024-11-05 / 0 评论 / 0 点赞 / 7 阅读 / 0 字 / 正在检测是否收录...

Spring 中获取 Bean 的八种方式

在使用 Spring 框架时,获取 Bean 的方式有很多种。本文将介绍八种常见的方式,并说明每种方式适用的场景。

1. 在初始化时保存 ApplicationContext 对象

适用于独立应用程序,在通过配置文件初始化 Spring 的时候保存 ApplicationContext 对象。

配置文件 (applicationContext.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="test" class="com.sxtx.bean.Test"/>
</beans>

代码示例

@Test
public void test() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    Test test = (Test) applicationContext.getBean("test");
    System.out.println(test);
}

2. 使用 Spring 提供的工具类获取 ApplicationContext 对象

适用于 B/S 系统,通过 ServletContext 对象获取 ApplicationContext,然后通过它获取所需的 Bean 实例。

ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(servletContext);
ac1.getBean("beanId");
ac2.getBean("beanId");
  • getRequiredWebApplicationContext 获取失败时抛出异常。
  • getWebApplicationContext 获取失败时返回 null

3. 实现 ApplicationContextAware 接口(推荐)

实现 ApplicationContextAware 接口的 setApplicationContext 方法,Spring 初始化时会将 ApplicationContext 注入到该类中。

@Component
public class SpringUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtils.applicationContext = applicationContext;
    }

    public static <T> T getBean(String beanName) {
        return applicationContext.containsBean(beanName) ? (T) applicationContext.getBean(beanName) : null;
    }

    public static <T> Map<String, T> getBeansOfType(Class<T> baseType) {
        return applicationContext.getBeansOfType(baseType);
    }
}

使用示例

User bean = SpringUtils.getBean("user");

4. 继承 ApplicationObjectSupport 抽象类

通过继承 ApplicationObjectSupport,使用 getApplicationContext() 方法获取 ApplicationContext 对象。

@Service
public class SpringContextHelper extends ApplicationObjectSupport {
    public Object getBean(String beanName) {
        return getApplicationContext().getBean(beanName);
    }
}

5. 继承 WebApplicationObjectSupport 抽象类

继承 WebApplicationObjectSupport,通过 getWebApplicationContext() 方法获取 WebApplicationContext

@Service
public class SpringContextHelper extends WebApplicationObjectSupport {
    public Object getBean(String beanName) {
        return getApplicationContext().getBean(beanName);
    }
}

6. 使用 BeanFactory 直接获取(不推荐)

使用 BeanFactory 从工厂中直接获取 Bean 实例。但由于 XmlBeanFactory 已废弃,建议尽量避免此方法。

@Test
public void test() {
    BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
    Test test = (Test) beanFactory.getBean("test");
    System.out.println(test);
}

7. 使用 ContextLoader 提供的 getCurrentWebApplicationContext 方法

适用于 Web 应用,通过 ContextLoader 获取当前 WebApplicationContext

@Test
public void test() {
    MockServletContext sc = new MockServletContext("");
    sc.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, "/applicationContext.xml");
    ServletContextListener listener = new ContextLoaderListener();
    ServletContextEvent event = new ServletContextEvent(sc);
    listener.contextInitialized(event);

    WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
    Test test = (Test) wac.getBean("test");
    System.out.println(test);
}

8. 实现 BeanFactoryPostProcessor 接口

通过实现 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法获取 ConfigurableListableBeanFactory 实例。

@Component
public final class SpringUtilsS implements BeanFactoryPostProcessor {
    private static ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        SpringUtilsS.beanFactory = beanFactory;
    }

    public static <T> T getBean(String name) throws BeansException {
        return (T) beanFactory.getBean(name);
    }

    public static boolean containsBean(String name) {
        return beanFactory.containsBean(name);
    }
}

扩展:BeanFactoryApplicationContext 的区别

BeanFactoryApplicationContext 是 Spring 中的两个核心接口,以下是两者的主要区别:

BeanFactory

  1. Spring 中最底层的接口,包含了 Bean 的定义、加载、实例化和生命周期管理。
  2. 采用延迟加载方式,即在调用 getBean() 时才实例化 Bean。配置错误会在调用 getBean 时才发现。
  3. 一般通过编程方式创建,占用内存小,适合轻量级应用。

ApplicationContext

  1. ApplicationContextBeanFactory 的子接口,提供了更多功能。
  2. 启动时即创建所有单例 Bean,方便检查配置错误。预加载所有单例 Bean 后,可以更快地获取它们。
  3. 占用更多内存,适合复杂的大型应用。
0

评论区