[Primavera] artículo de forma rápida para conocer la diferencia entre BeanFactory y FactoryBean

directorio

A, BeanFactory

1.1 Fuente

1.2 escenarios de uso

二, FactoryBean

2.1 Fuente

2.2 Ejemplo

2.2.1 Método uno

2.2.2 Método dos

Los dos usos 2.3 FactoryBean

2.3.1 simplificar el XML configuración ocultar detalles

2.3.2 devuelven diferentes instancias de la haba

2.4 escenarios de uso

Tres, BeanFactory y las diferencias y similitudes FactoryBean


A, BeanFactory

BeanFactory, poniendo fin a la fábrica, lo que indica que se trata de una clase de fábrica (Interface), que es responsable de una producción y dirección de la fábrica de frijol, podemos obtener la dirección de la fábrica de objetos a través de él. En primavera, la BeanFactory es COI contenedor interfaz de núcleo , sus responsabilidades incluyen : instanciar o aplicación de configuración de objetos y las dependencias entre esos objetos . Define getBean () , containsBean () y el otro método general de gestión de Bean. Pero sólo BeanFactory interfaces, no realización concreta contenedores COI, pero la primavera de contenedores para lograr dada la variedad, como por ejemplo:

  • DefaultListableBeanFactory
  • XmlBeanFactory
  • Application Context

 

XmlBeanFactory que es un uso general, esta aplicación se describirá dependencias XML entre los objetos y los objetos que componen la aplicación.

 

1.1 Fuente

public interface BeanFactory {
    /**
	用于区分factoryBean和bean,后面会讲到
    /*String FACTORY_BEAN_PREFIX = "&";

    /**
     返回byName返回bean的实例
	*/
    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;


    /**
     * Return a provider for the specified bean, allowing for lazy on-demand retrieval
     * of instances, including availability and uniqueness options.
     * @param requiredType type the bean must match; can be an interface or superclass
     * @return a corresponding provider handle
     * @since 5.1
     * @see #getBeanProvider(ResolvableType)
     */

    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    /**
	 判断工厂中是否包含给定名称的bean定义,若有则返回true
	*/
    boolean containsBean(String name);

    /**
    判断bean是否为单例
	*/
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    /**
	判断bean是否为多例
	*/
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    /**
	检查具有给定名称的bean是否匹配指定的类型。
     */
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    /**
	返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除*/
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    /**
	返回给定bean名称的所有别名 
	*/
    String[] getAliases(String name);
}

 

1.2 escenarios de uso

  • Haba adquirido de contenedor Ioc (Byname o byType)
  • recipiente Recuperando Ioc contiene el Bean especificado
  • Haba determina si singleton

 

二, FactoryBean

configuración XML, cuando los contenedores resorte, el resorte reflexión mediante el uso de <bean> atributo especifica la clase de la instancia de clase Bean, bajo ciertas circunstancias, el proceso de instanciación Bean es complejo, si la manera convencional, la necesidad de <bean > proporciona una gran cantidad de información de configuración. La flexibilidad de la disposición se limita, una dependencia tan pesada en otra clase de propiedades del objeto, incluso en este momento por un montaje automático, las dependencias entre el grano no tiene que escrito explícitamente, pero el objeto dependiente necesita ser instalado en el contenedor de primavera, también tienen que confiar en ella más que un grano de objetos de etiqueta se crean van a inyectar, si esta clase se basa en cientos de objetos, entonces este es sin duda una gran carga de trabajo.

clase de fábrica resorte proporciona la interfaz para este usuario org.springframework.bean.factory.FactoryBean puede crear una instancia de frijol por la lógica de la aplicación de esta personalización de la interfaz. FactoryBean las interfaces para el Spring Framework ocupan una posición importante, un resorte que proporciona su propia implementación de más de 70 FactoryBean. Se esconden los detalles de algunos de los ejemplos de complejos Bean, a la aplicación superior se hace más fácil. De principio Spring3.0, FactoryBean comenzó a apoyar, a saber, la declaración de interfaz genérico en lugar forma FactoryBean <T>.

Hay dos tipos de frijol de primavera, una para el frijol común, fue otra fábrica de beans

Finalización de Bean, que indica que es un Bean, Bean es diferente de lo común: se realiza FactoryBean <T> interfaz Bean, basado en la ID obtenida de la haba es en realidad la FactoryBean BeanFactory getObject () objeto devuelto FactoryBean lugar en sí, si se quiere obtener el objeto FactoryBean, añadir un símbolo de unión frente a la Identificación de conseguir.

 

2.1 Fuente

public interface FactoryBean<T> {
    //从工厂中获取bean
    @Nullable
    T getObject() throws Exception;

    //获取Bean工厂创建的对象的类型
    @Nullable
    Class<?> getObjectType();

    //Bean工厂创建的对象是否是单例模式
    default boolean isSingleton() {
        return true;
    }
}

Se puede observar a partir de la definición de interfaz, FactoryBean el ejercicio de las funciones de una planta. Es decir, si un Bean A FactoryBean implementa una interfaz, entonces A se convierte en una fábrica, adquirida bajo el nombre de A es en realidad una fábrica llama getObject () devuelve un objeto, en lugar de en sí A, si desea obtener la propia fábrica de A ejemplo, la necesidad de añadir '&' símbolo delante del nombre.

  • getObject ( 'nombre') devuelven una instancia de la planta
  • getObject ( '& nombre') devuelve una instancia de la propia planta,

 

En circunstancias normales, no hay necesidad de darse cuenta de su patrón de fábrica de beans, Primavera papel envases como una fábrica, pero unos pocos casos, el propio contenedor es una planta de frijol, es producir otras instancias del bean. Otros ejemplos de un grano de la planta de haba generado no generado por el contenedor Spring, tan diferente de la configuración de frijol ordinario, ya no es necesario proporcionar clase elementos.

 

2.2 Ejemplo

Ahora queremos la siguiente TempDaoFactoryBean clase a la fábrica para crear una gestión

public class TempDaoFactoryBean {
    private String msg1;
    private String msg2;
    private String msg3;

    public void test() {
        System.out.println("FactoryBean");
    }
    public void setMsg1(String msg1) {
        this.msg1 = msg1;
    }
    public void setMsg2(String msg2) {
        this.msg2 = msg2;
    }
    public void setMsg3(String msg3) {
        this.msg3 = msg3;
    }
    public String getMsg1() {
        return msg1;
    }
    public String getMsg2() {
        return msg2;
    }
    public String getMsg3() {
        return msg3;
    }
}

 Tenemos dos formas de elegir:

Método a configurar su resorte a través del XML.

Segundo método: definir una clase CarProxy lograr interfaz factoryBean.

 

2.2.1 Método uno

Si se utiliza un coche convencional dispuesto por debajo del <bean>, que corresponden respectivamente a cada atributo de un elemento <property> tag de coches, incluso si el uso de automatizado de montaje escribir también una gran cantidad de etiqueta <bean>, muy molesto

 

2.2.2 Método dos

FactoryBean aplicar las DaoFactoryBean interfaz definida

/**
 * FactoryBean由名字可以看出,是以bean结尾的,就说明这是一个bean,是由IOC容器管理的一个bean对象
 *
 * 如果你的类实现了FactoryBean
 * 那么spring容器当中会存储两个对象:一个是getObject()方法返回的对象(TempDaoFactoryBean),还有一个就是当前对象(DaoFactoryBean)
 *
 * getObject()返回的对象(TempDaoFactoryBean)存储在spring容器中给这个对象设置的beanName是当前类指定的对象,也就是     @Component("daoFactoryBean")  中的daoFactoryBean
 * 当前对象(DaoFactoryBean)在spring容器中设置的beanName是在@Component("")指定name的基础上加一个“&”,这里也就是&daoFactoryBean
 *  
 * ClassCastException类型转换异常
 */
public class DaoFactoryBean implements FactoryBean {
     // DaoFactoryBean这个工厂bean管理的对象
    private String msg;

    // 使用setter方法将其注入
    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void testBean() {
        System.out.println("testBean");
    }

    @Override
    public Object getObject() throws Exception {    
        // 在FactoryBean内部创建对象实例
        TempDaoFactoryBean temp = new TempDaoFactoryBean();
        String[] msfArray = msg.split(",");
           temp.setMsg1(msfArray[0]);
        temp.setMsg2(msfArray[1]);
        temp.setMsg3(msfArray[2]);
        return temp;
    }

    @Override
    public Class<?> getObjectType() {
        return TempDaoFactoryBean.class;
    }

    /**
     * 是否是单例
     * @return
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}

 XML utilizando este resorte se encaja en el recipiente factoryBean

<?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="daoFactory" class="priv.cy.dao.DaoFactoryBean">
        <property name="msg" value="msg1,msg2,msg3"></property>
    </bean>

</beans>

 

categorías de prueba:

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext
                = new AnnotationConfigApplicationContext(AppConfig.class);

        TempDaoFactoryBean tempDaoFactoryBean = (TempDaoFactoryBean) annotationConfigApplicationContext.getBean("daoFactory");
        System.out.println(tempDaoFactoryBean.getMsg1());
        System.out.println(tempDaoFactoryBean.getMsg2());
        System.out.println(tempDaoFactoryBean.getMsg3());
    }
}

 

Los resultados:

 

Porque cuando getBean, primavera FactoryBean de clases que implementan la interfaz para lograr un tratamiento especial

Cuando se llama a getBean ( "daoFactory") cuando, la primavera a través de la reflexión de descubrimiento DaoFactoryBean logra FactoryBean interfaz ,

En este caso el contenedor llama la primavera método de interfaz en devuelve el método getObject (). Si desea obtener una instancia de CarFactoryBean,

Con "y" se requiere prefijo antes beanName aparece cuando se utiliza el getBean (beanName) Método: como getBean ( "& car");  

 

2.3 FactoryBean dos usos de

 

2.3.1 simplificar los xml de configuración, detalles ocultos

Si una clase tiene una gran cantidad de atributos, queremos inyectar el valor de los atributos de clase primavera, está obligado a escribir una gran cantidad de atributos configurados en el archivo de configuración, lo que resulta en el archivo de configuración hinchada, entonces se puede considerar usarlo para simplificar la configuración FactoryBean

 

nuevo bean

public class Student {
    /** 姓名 */
    private String name;
    /** 年龄 */
    private int age;
    /** 班级名称 */
    private String className;
    public Student() {
    }
    public Student(String name, int age, String className) {
        this.name = name;
        this.age = age;
        this.className = className;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", age=" + age + ", className='" + className + '\'' + '}';
    }
}

 

Interfaz de aplicación FactoryBean

public class StudentFactoryBean implements FactoryBean<Student> {
    private String studentInfo;
    @Override
    public Student getObject() throws Exception {
        if (this.studentInfo == null) {
            throw new IllegalArgumentException("'studentInfo' is required");
        }
        String[] splitStudentInfo = studentInfo.split(",");
        if (null == splitStudentInfo || splitStudentInfo.length != 3) {
            throw new IllegalArgumentException("'studentInfo' config error");
        }

        Student student = new Student();
        student.setName(splitStudentInfo[0]);
        student.setAge(Integer.valueOf(splitStudentInfo[1]));
        student.setClassName(splitStudentInfo[2]);
        return student;
    }
    @Override
    public Class<?> getObjectType() {
        return Student.class;
    }
    public void setStudentInfo(String studentInfo) {
        this.studentInfo = studentInfo;
    }
}

 

Nuevo perfil day03.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">
    <!--注意:class是StudentFactoryBean而不是Student-->
    <bean id="student" class="com.lyc.cn.day03.StudentFactoryBean" p:studentInfo="张三,25,三年二班"/>
</beans>

 

Categoría de prueba

public class MyTest {
    @Before
    public void before() {
        System.out.println("---测试开始---\n");
    }
    @After
    public void after() {
        System.out.println("\n---测试结束---");
    }
    @Test
    public void testStudentFactoryBean() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("day03.xml");
        System.out.println(applicationContext.getBean("student"));
        System.out.println(applicationContext.getBean("&student"));
    }
}

 

corrida

---测试开始---

Student{name='张三', age=25, className='三年二班'}

org.springframework.beans.factory_bean.StudentFactoryBean@1ae369b7

---测试结束---

 

这样我们就实现了通过BeanFactory接口达到了简化配置文件的作用。另外大家也可以发现getBean(“student”)返回的Student类的实例;而getBean("&student")返回的是StudentFactoryBean实例,即工厂bean其本身。

 

2.3.2 retorno diferentes de haba casos

Desde FactoryBean es una fábrica de beans, entonces podemos ser requeridos dependiendo del tipo de rendimientos a diferentes instancias del frijol, por explicar brevemente el código

 

nuevo bean

public interface Animal {
    void sayHello();
}

public class Cat implements Animal {
    @Override
    public void sayHello() {
        System.out.println("hello, 喵喵喵...");
    }
}

public class Dog implements Animal {
    @Override
    public void sayHello() {
        System.out.println("hello, 汪汪汪...");
    }
}

interfaz de animales crea un extremadamente dos clases de implementación de gato y perro, y una salida sencilla, cómo devolver una instancia diferente de animales configurarlo por FactoryBean

 

nueva AnimalFactoryBean

public class AnimalFactoryBean implements FactoryBean<Animal> {
    private String animal;

    @Override
    public Animal getObject() throws Exception {
        if (null == animal) {
            throw new IllegalArgumentException("'animal' is required");
        }
        if ("cat".equals(animal)) {
            return new Cat();
        } else if ("dog".equals(animal)) {
            return new Dog();
        } else {
            throw new IllegalArgumentException("animal type error");
        }
    }

    @Override
    public Class<?> getObjectType() {
        if (null == animal) {
            throw new IllegalArgumentException("'animal' is required");
        }
        if ("cat".equals(animal)) {
            return Cat.class;
        } else if ("dog".equals(animal)) {
            return Dog.class;
        } else {
            throw new IllegalArgumentException("animal type error");
        }
    }
    public void setAnimal(String animal) {
        this.animal = animal;
    }
}

 

Day03.xml modificar el archivo de configuración, añadir el frijol

<bean id="animal" class="com.lyc.cn.day03.AnimalFactoryBean" p:animal="cat"/>

 

Añadir un caso de prueba en el MyTest

@Test
public void testAnimalFactoryBean() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("day03.xml");
    Animal animal = applicationContext.getBean("animal", Animal.class);
    animal.sayHello();
}

 

corrida

---测试开始---

hello, 喵喵喵...

---测试结束---

可以看到,配置文件里我们将animal配置成了cat,那么返回的就是cat的实例,也是简单工厂的一个实现

 

 

2.4 Uso de escena

Una vez dicho esto, ¿por qué tiene FactoryBean esto hace, qué papel específico?

 

FactoryBean En primavera la aplicación más típica se utiliza para crear un objeto proxy AOP.

Sabemos que la primavera AOP se crea realmente en tiempo de ejecución de un objeto proxy, ese objeto, hemos creado en tiempo de ejecución, en lugar de la definición de un comienzo bueno, lo cual está en línea con el patrón método de fábrica. hablando en sentido figurado Más, AOP objeto proxy a través de mecanismo de reflexión de Java para crear un objeto proxy en tiempo de ejecución, el método de proxy del objeto de destino basado en los requisitos de negocio tejidas en un método correspondiente. Este objeto es en --ProxyFactoryBean resorte.

Así, FactoryBean proporciona una manera más flexible para nosotros crear una instancia de Bean, podemos crear una instancia de frijol más sofisticado por FactoryBean.

 

Por ejemplo, todavía primavera necesidad de integrar mybatis, en ausencia de primavera-mybatis caso de (primavera-mybatis le ayudará a MyBatis  código se integra perfectamente en la primavera  en ), tenemos que MyBatis clases básicas SqlSessionFactory inyecta en el muelle de contenedores, entonces pensamos el más comúnmente utilizado de dos maneras:

  1. Notas , sin embargo mybatis se referencia independiente de nuestro proyecto . No hay nada que ver con nuestro propio código fuente del proyecto , no somos capaces de modificar su código fuente, añadir anotaciones de su origen, por lo que no puede utilizar métodos de anotación
  2. xml, sqlSessionFacory necesidad de inyectar una gran cantidad de dependencias , si utiliza XML para configurar, tenemos que escribir un montón de etiqueta de configuración, muy inconveniente de mantener.

Una clase de proxy se puede seleccionar para manejar sqlSessionFacory, es decir, que la integración de la primavera + uso mybatis SqlSessionFactoryBean de esta clase es proporcionado por nuestro rápido factoryBean mybatis utiliza para facilitar la configuración mybatis por el código de clase para una gran cantidad de paquete de configuración complicada arriba, similar al patrón decorador, SqlSessionFactoryBean dentro de los parámetros de configuración y gestión sqlSessionFacory relacionados con su funcionamiento, sólo tenemos que SqlSessionFactoryBean inyecta en el recipiente de la primavera y la información de configuración sencilla pasado al factoryBean en XML, SqlSessionFactoryBean que nos ayudará a configurar automáticamente sqlSessionFacory, muchas configuraciones complejas para ayudar a llenar el sqlSessionFacory hecho bien, entonces podemos obtener configurado por SqlSessionFactoryBean.

 

Tres, BeanFactory y FactoryBean diferencias y similitudes

Comunes: todas las interfaces

diferencia:

  • BeanFactory terminando fábrica de, lo que indica que se trata de una clase de fábrica para la gestión de una fábrica Bean. En la primavera, Bean son todos a ser administrado por el BeanFactory (es decir, recipiente COI). La interfaz es la interfaz de nivel superior de contenedores IoC es la aplicación más básica COI contenedor, sino también el acceso a la raíz interfaz contenedor primavera, responsable de la creación de frijol, acceso, etc.
  • Para FactoryBean, terminando el Bean, afirmó que se trata de un contenedor determinado para gestionar el grano. Esto no es un simple grano de frijol, pero una generación capaz de producir o modificar objetos planta de frijol, de forma similar a su modelo de aplicación y el diseño del modelo de fábrica y el modo de modificación.

referencias:https://blog.csdn.net/lyc_liyanchao/article/details/82424122

Publicado 54 artículos originales · ganado elogios 47 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/cy973071263/article/details/104758856
Recomendado
Clasificación