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);
}
}
扩展:BeanFactory
与 ApplicationContext
的区别
BeanFactory
和 ApplicationContext
是 Spring 中的两个核心接口,以下是两者的主要区别:
BeanFactory
- Spring 中最底层的接口,包含了 Bean 的定义、加载、实例化和生命周期管理。
- 采用延迟加载方式,即在调用
getBean()
时才实例化 Bean。配置错误会在调用getBean
时才发现。 - 一般通过编程方式创建,占用内存小,适合轻量级应用。
ApplicationContext
ApplicationContext
是BeanFactory
的子接口,提供了更多功能。- 启动时即创建所有单例 Bean,方便检查配置错误。预加载所有单例 Bean 后,可以更快地获取它们。
- 占用更多内存,适合复杂的大型应用。
评论区