写点什么

Spring 中获取 bean 的八种方式,你 get 了几种?

作者:小小怪下士
  • 2022-11-25
    湖南
  • 本文字数:3932 字

    阅读完需:约 13 分钟

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

适用于 Spring 框架的独立应用程序,须要程序通过配置文件初始化 Spring。


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"       xmlns:p="http://www.springframework.org/schema/p"       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"></bean>
</beans>
复制代码


代码:


@Testpublic void test() {    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");    //ApplicationContext applicationContext = new FileSystemXmlApplicationContext("applicationContext.xml");     Test test= (Test) applicationContext.getBean("test");    System.out.println(test);}
复制代码

2、通过 Spring 提供的工具类获取 ApplicationContext 对象

适合于 Spring 框架的 B/S 系统,通过ServletContext对象获取ApplicationContext对象。然后在通过它获取须要的类实例。以下两个工具方式的差别是,前者在获取失败时抛出异常。后者返回 null。


ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc); ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc); ac1.getBean("beanId"); ac2.getBean("beanId");  
复制代码

3、实现接口 ApplicationContextAware(推荐)

实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring 初始化时,扫描到该类,就会通过该方法将ApplicationContext对象注入。然后在代码中就可以获取 spring 容器 bean 了。


例如:


User bean = SpringUtils.getBean(“user”);


@Componentpublic 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) { if(applicationContext.containsBean(beanName)){ return (T) applicationContext.getBean(beanName); }else{ return null; } } public static <T> Map<String, T> getBeansOfType(Class<T> baseType){ return applicationContext.getBeansOfType(baseType); }}
复制代码

4、继承自抽象类 ApplicationObjectSupport

调用父类的getApplicationContext()方法,获取 Spring 容器对象。


@Servicepublic class SpringContextHelper extends ApplicationObjectSupport {
public Object getBean(String beanName) { return getApplicationContext().getBean(beanName); }}
复制代码

5、继承自抽象类 WebApplicationObjectSupport

调用getWebApplicationContext()获取WebApplicationContext


@Servicepublic class SpringContextHelper extends WebApplicationObjectSupport {
public Object getBean(String beanName) { return getApplicationContext().getBean(beanName); }}
复制代码

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

使用BeanFactory从工厂中直接获取 Bean 实例,但是XmlBeanFactory类已经废弃,因此不建议使用。


@Testpublic void test() {    BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));    Test test= (Test) beanFactory.getBean("test");    System.out.println(test);}
复制代码

7、使用 ContextLoader 提供的 getCurrentWebApplicationContext 方法

@Testpublic 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

spring 工具类 方便在非 spring 管理环境中获取 bean


@Componentpublic final class SpringUtilsS implements BeanFactoryPostProcessor{    /** Spring应用上下文环境 */    private static ConfigurableListableBeanFactory beanFactory;
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtilsS.beanFactory = beanFactory; }
/** * 获取对象 * * @param name * @return Object 一个以所给名字注册的bean的实例 * @throws BeansException * */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T) beanFactory.getBean(name); }
/** * 获取类型为requiredType的对象 * * @param clz * @return * @throws BeansException * */ public static <T> T getBean(Class<T> clz) throws BeansException { T result = (T) beanFactory.getBean(clz); return result; }
/** * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true * * @param name * @return boolean */ public static boolean containsBean(String name) { return beanFactory.containsBean(name); }
/** * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) * * @param name * @return boolean * @throws NoSuchBeanDefinitionException * */ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return beanFactory.isSingleton(name); }
/** * @param name * @return Class 注册对象的类型 * @throws NoSuchBeanDefinitionException * */ public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { return beanFactory.getType(name); }
/** * 如果给定的bean名字在bean定义中有别名,则返回这些别名 * * @param name * @return * @throws NoSuchBeanDefinitionException * */ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { return beanFactory.getAliases(name); }
/** * 获取aop代理对象 * * @param invoker * @return */ @SuppressWarnings("unchecked") public static <T> T getAopProxy(T invoker) { return (T) AopContext.currentProxy(); }}
复制代码

扩展

BeanFactoryApplicationContext是 Spring 的两大核心接口,都可以当做 Spring 的容器。其中ApplicationContextBeanFactory的子接口。

BeanFactory

(1)、是 Spring 里面最底层的接口(最原始的接口),包含了各种 Bean 的定义,读取 bean 配置文档,管理 bean 的加载、实例化,控制 bean 的生命周期,维护 bean 之间的依赖关系。


(2)、采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean 时(调用getBean()),才对该 Bean 进行加载实例化。这样,我们就不能发现一些存在的 Spring 的配置问题。如果 Bean 的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用 getBean 方法才会抛出异常。


(3)BeanFactory通常以编程的方式被创建。


(4)BeanFactoryApplicationContext都支持BeanPostProcessorBeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。


(5) 占用内存小。

ApplicationContext

1、ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:


  • 继承MessageSource,因此支持国际化。

  • 统一的资源文件访问方式。

  • 提供在监听器中注册 bean 的事件。

  • 同时加载多个配置文件。

  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的 web 层。


2、ApplicationContext,它是在容器启动时,一次性创建了所有的 Bean。这样,在容器启动时,我们就可以发现 Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例 Bean,通过预载入单实例 bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。


3、ApplicationContext 占用内存空间大,当程序的配置 bean 特别多时,程序启动慢。


4、ApplicationContext 能以编程式方式创建,还能能以声明的方式创建,如使用ContextLoader

用户头像

还未添加个人签名 2022-09-04 加入

热衷于分享java技术,一起交流学习,探讨技术。 需要Java相关资料的可以+v:xiaoyanya_1

评论

发布
暂无评论
Spring中获取bean的八种方式,你get了几种?_Java_小小怪下士_InfoQ写作社区