Spring

总结

BeanFactory和FactoryBean其实没有什么比较性的,只是两者的名称特别接近,所以有时候会拿出来比较一番。

  • BeanFactory是提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范。
  • FactoryBean可以说为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。

BeanFactory

  • BeanFactory是一个接口,提供了IOC容器最基本的形式(包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖),给具体的IOC容器的实现(如:ApplicationContext接口,XmlBeanFactory)提供了规范。
  • BeanFactory接口是无法支持spring的许多插件,如AOP功能、Web应用等。
  • ApplicationContext接口,它由BeanFactory接口派生而来。ApplicationContext包含BeanFactory的所有功能。
package org.springframework.beans.factory;  
import org.springframework.beans.BeansException;  
public interface BeanFactory {  
    String FACTORY_BEAN_PREFIX = "&";  
    Object getBean(String name) throws BeansException;  //返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
    <T> T getBean(String name, Class<T> requiredType) throws BeansException; //返回以给定名称注册的bean实例,并转换为给定class类型 
    <T> T getBean(Class<T> requiredType) throws BeansException;  
    Object getBean(String name, Object... args) throws BeansException;  
    boolean containsBean(String name);  //判断工厂中是否包含给定名称的bean定义,若有则返回true
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  //判断给定名称的bean定义是否为单例模式
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;  
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;  //返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
    String[] getAliases(String name);  //返回给定bean名称的所有别名
}

FactoryBean

  • FactoryBean是一个(工厂类)接口,通过实现该接口,定制实例化Bean的逻辑。(在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。)
  • FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,我们可以在getObject()方法中灵活配置。
  • 当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

FactoryBean源码

package org.springframework.beans.factory;  
public interface FactoryBean<T> {  
    T getObject() throws Exception;  
    Class<?> getObjectType();  
    boolean isSingleton();  
}

FactoryBean的实现类

import org.springframework.beans.factory.FactoryBean;
 
/** 
 * @author  作者 wangbiao
 * @date 创建时间:2016年11月14日 上午11:19:31 
 * @parameter 
 * @return 
 */
public class FactoryBeanPojo implements FactoryBean{
    private String type;
 
    @Override
    public Object getObject() throws Exception {
        if("student".equals(type)){
            return new Student();            
        }else{
            return new School();
        }
        
    }
 
    @Override
    public Class getObjectType() {
        return School.class;
    }
 
    @Override
    public boolean isSingleton() {
        return true;
    }
 
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
    
}

普通的bean

/** 
 * @author  作者 wangbiao
 * @date 创建时间:2016年11月14日 上午11:13:18 
 * @parameter 
 * @return 
 */
public class School {
    private String schoolName;
    private String address;
    private int studentNumber;
    public String getSchoolName() {
        return schoolName;
    }
    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getStudentNumber() {
        return studentNumber;
    }
    public void setStudentNumber(int studentNumber) {
        this.studentNumber = studentNumber;
    }
    @Override
    public String toString() {
        return "School [schoolName=" + schoolName + ", address=" + address
                + ", studentNumber=" + studentNumber + "]";
    }
}

XML配置

<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context-3.0.xsd
                     http://www.springframework.org/schema/aop
                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                     http://www.springframework.org/schema/tx
                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
 <bean id="student" class="com.spring.bean.Student">  
  <property name="name" value="zhangsan" />  
 </bean>  
 
 <bean id="school" class="com.spring.bean.School">  
 </bean> 
 
 <bean id="factoryBeanPojo" class="com.spring.bean.FactoryBeanPojo">  
    <property name="type" value="student" />
 </bean> 
</beans> 

测试类

import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.spring.bean.FactoryBeanPojo;
 
/** 
 * @author  作者 wangbiao
 * @date 创建时间:2016年11月14日 上午11:11:35 
 * @parameter 
 * @return 
 */
public class FactoryBeanTest {
    public static void main(String[] args){
        String url = "com/spring/config/BeanConfig.xml";
        ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
        Object school=  cpxa.getBean("factoryBeanPojo");
        FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");
        System.out.println(school.getClass().getName());
        System.out.println(factoryBeanPojo.getClass().getName());
    }
}

输出的结果:

loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [com/spring/config/BeanConfig.xml]
com.spring.bean.Student
com.spring.bean.FactoryBeanPojo

从结果上可以看到当从IOC容器中获取FactoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设置为student的时候,会在getObject()方法中返回Student对象。所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject方法返回的对象,要想获取FactoryBean的实现类,得在getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanName)。

参考文献

版权声明:本文为CSDN博主「wangbiao007」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:

https://blog.csdn.net/wangbiao007/article/details/53183764

https://www.cnblogs.com/aspirant/p/9082858.html

原文地址:https://www.cnblogs.com/frankcui/p/14539145.html