• 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

  • 相关阅读:
    mybatis中一直获取xml配置文件输入流值为空的类似解决方法
    switch中能有的值都有哪些
    length,length(),size()
    Spring中IOC的基本原理
    ajax中的一些小问题
    Servlet简单业务流程
    推荐用字节流处理文件拷贝
    更有效率的数据交换
    1.7版本处理io流自动关闭流的写法
    集合中的简单知识
  • 原文地址:https://www.cnblogs.com/frankcui/p/14539145.html
Copyright © 2020-2023  润新知