`

在Spring BeanFactory容器中管理两种bean

 
阅读更多

在Spring BeanFactory容器中管理两种bean  

1.标准Java Bean  

2,另一种是工厂Bean,   即实现了FactoryBean接口的bean  它不是一个简单的Bean 而是一个生产或修饰对象生成的工厂Bean

在向Spring容器获得bean时  对于标准的java Bean  返回的是类自身的实例 

而FactoryBean 其返回的对象不一定是自身类的一个实例,返回的是该工厂Bean的getObject方法所返回的对象

一个简单的例子

  1. public class SayHelloFactoryBeanImpl implements FactoryBean {  
  2.   
  3.     /** 
  4.      * 返回该工厂生成的bean 
  5.      */  
  6.     public Object getObject() throws Exception {  
  7.         return new ChinaSayHelloServiceImpl();  
  8.     }  
  9.   
  10.     /** 
  11.      * getObject返回对象对应的Class 
  12.      */  
  13.     public Class getObjectType() {  
  14.         return ChinaSayHelloServiceImpl.class;  
  15.     }  
  16.       
  17.     /** 
  18.      * getObject返回的对象 是否是一个单例 
  19.      */  
  20.     public boolean isSingleton() {  
  21.         return false;  
  22.     }  
  23. }  
  1. 配置文件  
  2. <bean id="sayHelloFactoryBean" class="com.xx.service.impl.SayHelloFactoryBeanImpl" />  
  1. ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true);  
  2. //bean的 getObject方法 返回的对象   
  3. Object object = context.getBean("sayHelloFactoryBean");  
  4. System.out.println(object);  

控制台输出

com.xx.service.impl.ChinaSayHelloServiceImpl@1f66cff

容器返回的是 bean getObject方法返回对象  而不是SayHelloFactoryBeanImpl自身的实例 当然可以用“&”符号转义 获得FactoryBean的自身实例

  1. ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-server.xml"}, true);  
  2.         //可以用转义符"&"来获得FactoryBean本身实例          
  3.         System.out.println(context.getBean("&sayHelloFactoryBean"));  

控制台输出

com.xx.service.impl.SayHelloFactoryBeanImpl@75e4fc

下面看看FactoryBean是怎么实现的

Spring  FactoryBean接口定义

  1. public interface FactoryBean {  
  2.   
  3.     Object getObject() throws Exception;  
  4.   
  5.     Class getObjectType();  
  6.   
  7.     boolean isSingleton();  
  8. }  

bean的实例化 是在AbstractBeanFactory getBean方法发生的

  1. public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {  
  2.         return doGetBean(name, requiredType, args, false);  
  3.     }  
  1. protected Object doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {  
  2.         // bean name处理  如果是以"&"开头  截取掉     
  3.         final String beanName = transformedBeanName(name);  
  4.         Object bean = null;  
  5.         //单例的bean 只实例化一次  第一次实例化后会放到一个Map中 即singletonObjects map集合中  下次使用的时候直接拿   
  6.         Object sharedInstance = getSingleton(beanName);  
  7.         if (sharedInstance != null && args == null) {  
  8.             // FactoryBean 相关处理 在此方法发生   
  9.             //name 调用getBean时传入的参数    
  10.             //beanName 截取"&"后的name   
  11.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
  12.         }  
  13.   
  14.         else {  
  15.             ...略  
  16.         }  
  17.         return bean;  
  18. }  
  1. protected Object getObjectForBeanInstance(  
  2.         Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  
  3.     // 如果不是FactoryBean的相关调用 结束处理   
  4.     //isFactoryDereference 方法判断name 是不是以"&"开始  如果以"&"开始 返回true   
  5.     if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {  
  6.         throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());  
  7.     }  
  8.     if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {  
  9.         return beanInstance;  
  10.     }  
  11.     Object object = null;  
  12.     //bean的定义为null   
  13.     if (mbd == null) {  
  14.         //缓存集合factoryBeanObjectCache中包含  当前bean getObject方法返回的实例  不需要在调用 直接返回   
  15.         object = getCachedObjectForFactoryBean(beanName);  
  16.     }  
  17.     if (object == null) {  
  18.         FactoryBean factory = (FactoryBean) beanInstance;  
  19.         //containsBeanDefinition方法->  bean的定义map beanDefinitionMap集合中 是否包含该bean的定义   
  20.         if (mbd == null && containsBeanDefinition(beanName)) {  
  21.             mbd = getMergedLocalBeanDefinition(beanName);  
  22.         }  
  23.         boolean synthetic = (mbd != null && mbd.isSynthetic());  
  24.         // FactoryBean getObject触发   并缓存到factoryBeanObjectCache集合中   
  25.         object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
  26.     }  
  27.     return object;  
  28. }  
  1. protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {  
  2.     //当前的factoryBean是否单例  并且  缓存singletonObjects‘Map中包含FactoryBean的自身实例   
  3.     if (factory.isSingleton() && containsSingleton(beanName)) {  
  4.         synchronized (getSingletonMutex()) {  
  5.             // factoryBeanObjectCache 缓存的是 getObject返回的对象   
  6.             Object object = this.factoryBeanObjectCache.get(beanName);  
  7.             if (object == null) {  
  8.                 //getObject方法调用   
  9.                 object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
  10.                 //缓存 getObject方法返回的实例对象   
  11.                 this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));  
  12.             }  
  13.             return (object != NULL_OBJECT ? object : null);  
  14.         }  
  15.     }  
  16.     else {  
  17.         //getObject方法调用   
  18.         return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);  
  19.     }  
  20. }  
  1. private Object doGetObjectFromFactoryBean(  
  2.         final FactoryBean factory, final String beanName, final boolean shouldPostProcess)  
  3.         throws BeanCreationException {  
  4.     AccessControlContext acc = AccessController.getContext();  
  5.     return AccessController.doPrivileged(new PrivilegedAction() {  
  6.         public Object run() {  
  7.             Object object;  
  8.   
  9.             try {  
  10.                 // getObject方法调用   
  11.                 object = factory.getObject();  
  12.             }  
  13.             catch (FactoryBeanNotInitializedException ex) {  
  14.                 throw new BeanCurrentlyInCreationException(beanName, ex.toString());  
  15.             }  
  16.             catch (Throwable ex) {  
  17.                 throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);  
  18.             }  
  19.             if (object == null && isSingletonCurrentlyInCreation(beanName)) {  
  20.                 throw new BeanCurrentlyInCreationException(  
  21.                         beanName, "FactoryBean which is currently in creation returned null from getObject");  
  22.             }  
  23.   
  24.             if (object != null && shouldPostProcess) {  
  25.                 try {  
  26.                     object = postProcessObjectFromFactoryBean(object, beanName);  
  27.                 }  
  28.                 catch (Throwable ex) {  
  29.                     throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);  
  30.                 }  
  31.             }  
  32.   
  33.             return object;  
  34.         }  
  35.     }, acc);  
  36. }  

当一个受Spring容器管理的bean  如果实现了FactoryBean接口  在bean实例化(getBean)阶段  Spring会调用该bean的getObejct方法 返回的不一定是自身的实例

Spring 框架中有很多FactoryBean   例如RmiProxyFactoryBean, SqlMapClientFactoryBean. LocalSessionFactoryBean等都是通过FactoryBean getObject方法驱动起来的.对bean的生产 修饰做了很好的封装。

分享到:
评论

相关推荐

    Spring之核心容器bean

    在Spring中,bean是一个由容器管理的对象,它的实例化、初始化、装配和销毁都是由Spring容器控制的。你可以通过XML、注解或者Java配置类来定义bean。例如,一个简单的XML配置如下: ```xml &lt;bean id="myBean" class...

    Spring中ApplicationContext和beanfactory区别.rar

    在Spring框架中,ApplicationContext和BeanFactory是两种不同的bean容器,它们各自有其特性和应用场景,理解二者的区别对于深入学习和使用Spring至关重要。 首先,BeanFactory是Spring中最基础的bean管理容器,它...

    Spring bean 管理

    在Spring中,Bean的管理包含多个方面:创建Bean实例、配置Bean属性、控制Bean的生命周期以及Bean作用域的定义。接下来将详细解释这些知识点。 1. Spring的工厂类: Spring通过工厂模式设计了一系列工厂类来创建对象...

    Web项目中获取SpringBean与在非Spring组件中获取SpringBean.pdf

    总的来说,获取非Spring管理组件中的SpringBean主要有两种方式:一是通过实现`ApplicationContextAware`接口并存储ApplicationContext,二是使用注解和静态内部类来注入BeanFactory。这两种方法都是Spring框架提供的...

    day38 05-Spring的BeanFactory与ApplicationContext区别

    在Spring框架中,BeanFactory和ApplicationContext是两种不同的bean容器,它们各自有其特性和应用场景,理解二者的区别对于深入掌握Spring框架至关重要。 首先,BeanFactory是Spring中最基本的bean容器,它提供了对...

    Spring的Bean配置

    Spring提供了两种主要的IOC容器:`BeanFactory`和`ApplicationContext`。 - `BeanFactory`是最基本的容器,它实现了IoC的基本功能,如Bean的创建和管理。然而,它的功能相对较少,适合小型项目。 - `...

    获取Spring容器

    Spring提供了两种主要类型的容器: 1. **BeanFactory**:这是最基本的容器,提供配置Bean以及创建Bean的功能。 2. **ApplicationContext**:它继承了BeanFactory的功能,提供了更高级的服务,如资源访问、消息资源...

    Spring中与Bean相关的接口

    它是Spring中最基本的Bean容器,负责创建、配置和管理Bean。`BeanFactory`提供了一个延迟初始化Bean的能力,这意味着Bean只在真正被请求时才会被实例化,这有助于提高应用的启动速度。例如,当使用`XmlBeanFactory`...

    Java中Spring获取bean方法小结

    - **BeanFactory** 是Spring中最基础的IoC容器,负责管理和实例化Bean。它允许开发者定义Bean的生命周期和依赖关系,提供了低级别的配置选项。 - **ApplicationContext** 是BeanFactory的扩展,增加了更多面向应用...

    Spring容器 .ppt

    Spring容器是Spring框架的基石,主要分为两种类型:`BeanFactory`和`ApplicationContext`。`BeanFactory`是最基本的容器,而`ApplicationContext`则提供了更多的企业级功能,如国际化支持、事件发布、AOP代理等。...

    Spring的IoC容器初始化源码解析

    在Spring中,IoC容器主要分为两大类:`BeanFactory`和`ApplicationContext`。 ##### 3.1 BeanFactory简介 `BeanFactory`是最基本的IoC容器实现,它主要负责创建和管理bean的生命周期。BeanFactory提供了一系列基础...

    Spring和SpringMVC父子容器关系

    Spring容器主要分为两种类型:ApplicationContext和BeanFactory。ApplicationContext是Spring中最常用的容器,它提供了更高级的功能,如对国际化、事件传播、资源加载等的支持。BeanFactory是Spring的基本容器,负责...

    spring 容器.docx

    这两种接口都是用来表示Spring容器,它们的主要职责是创建Bean实例并管理这些实例。 BeanFactory作为Spring的基础容器接口,提供了诸如Bean的创建、配置和管理等功能。它包含了几个关键的方法,如`containBean...

    spring容器简单实例

    主要有两种类型的容器:BeanFactory和ApplicationContext。BeanFactory是最基础的容器,而ApplicationContext提供了更多的企业级服务,如国际化、事件传播等。在实际开发中,我们通常使用ApplicationContext。 2. *...

    Spring学习笔记,精华摘要

    在Spring框架中,工厂模式体现在Spring容器(BeanFactory或ApplicationContext)中,容器根据配置文件或编程方式来创建和管理bean。Spring容器不仅能创建bean,还能处理bean的生命周期,包括初始化、装配、管理和...

    Spring中Bean的生命周期 applicationcontext的应用(实现国际化,事件的传递)

    在Spring框架中,Bean的生命周期管理和ApplicationContext的应用是两个核心概念,它们对于理解Spring如何管理和协调应用中的对象至关重要。本文将深入探讨这两个主题,并结合国际化(i18n)和事件传递来阐述它们在...

    spring技术详解

    Spring技术详解 Spring技术详解是Java框架中的一种重要技术,主要用于解决Java应用程序...Spring容器和被管理的Bean是Spring技术的核心组成部分,ApplicationContext是BeanFactory的子接口,用于管理Spring中的Bean。

    几种spring获取bean的方法.txt

    通过以上两种方法,我们可以在Spring应用中灵活地获取所需的Bean实例。第一种方法适用于Web应用环境,而第二种方法则更加通用,可以在任何环境中使用。这两种方式都避免了硬编码Bean的获取逻辑,使得代码更加灵活和...

    详解Spring IOC 容器启动流程分析

    在 Spring 框架中,BeanFactory 是一个核心组件,它提供了一个统一的接口来访问容器中的 Bean。BeanFactory 是 IOC 容器的操作工具,它提供了许多方法来操作容器中的 Bean,例如 getBean() 方法和 containsBean() ...

    spring学习之路(黑马课程笔记)

    在Spring框架中,Bean的延迟加载是指在业务层等各种功能bean中使用延迟加载的技术来提高系统的性能。在引入springMVC后,Bean的延迟加载将变得更加重要。 Bean的初始化函数和销毁函数 在Spring框架中,Bean的初始...

Global site tag (gtag.js) - Google Analytics