基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

一:Spring创建复杂对象

1:复杂对象概念

        什么是复杂对象?什么是简单对象?
        1:简单对象,直接通过new 构造方法创建的对象
        2:复杂对象,不能通过直接new构造方法的创建的对象

        补充说明:
        1:这些复杂对象大多都是Spring集成的一些其他优秀的框架中的核心类的对象,不能直接new,我们也希望Spring能够创建这些类的对象,保证Spring工厂什么对象都可以创建

         2:Spring容器就是Spring工厂

2:常见的复杂对象

        链接对象和SqlSessionFactory对象。

二:基于FactoryBean创建复杂对象

1:概述

         这种方式的本质在一个实现了BeanFactory这样的接口的Bean中,书写创建该复杂对象的代码,这样通过Bean对应id获取到的Bean是复杂对象的Bean而不是这个Bean的对象,Spring非常重要的一种机制,Spring原生提供的帮我们创建复杂对象的方式。

2:开发步骤

        1:实现FactoryBean接口,在该类的getBean()方法代码中创建该类对象
        2:在Spring的核心配置文件中配置这个类
        3:通过这个工厂对象中的getBean方法获取该复杂对象

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

3:FactoryBean的Method

        getObject()获取该复杂对象,调用这个方法获取到复杂对象,然后在调用Spring工厂对象进行getBean的时候将这个复杂对象进行返回

        获取该复杂对象的Class对象,此对象也是Spring工厂进行调用

        isSingleTon()这个方法返回的事true或者false如果是true的话,表示的是单例设计模式,每次getBean的时候,获取的都是这一个对象,不会多次创建,如果是false的话,每次创建都会创建一个新的复杂对象,返回的也是新的复杂对象

        补充说明:
        他这个复杂对象的创建每个跟每个都不一样,所以,Spring是给定了接口,将对象创建的核心代码让你来写

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

4:Spring配置文件中的配置

        配置文件当中这样写理论上Spring为我们创建的ConnectionFactoryBean的对象,但是我们使用getBean方法进行获取时候,获取的不再是这个类的对象,而是我们希望获取的所创建的复杂的对象
基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

 

5:FactoryBean开发细节

        如果这个类型是FactoryBean类型的实现,我们获取的是复杂对象,如果我们就想获取这个FactoryBean类型的对象怎么办?getBean的时候,在id前面加上一个&符号,类似于getBean("&conn")这样的话就获取的是FactoryBean类型的对象,isSingleTon()方法返回true的时候,只会创建一个对象,返回false的时候,每次获取spring都会创建一个对象。

        Connection对象能够共用?

        不能公用,链接对象一个很大的作用在于控制事务,假设一个链接开启了事务,假设两个用户都获取到了conn这个对象,你使用这个对象提交了事务,就影响到了我,那就不行。SqlSessionFactory这个对象是线程安全的,重量级的,之创建一次,应该创建一次,应该设置成true。

        获取Connnection对象的时候的一些细节?

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

        我们对于依赖注入的体会

        通过依赖注入的思想,将写死的内容变成成员变量,然后交由Spring进行依赖注入。获得解耦合的好处。把Connection依赖的四个字符串信息,进行了依赖注入,好处就是解耦合。

        为什么Spring要规定一个factoryBean接口要我们实现,并且将创建复杂对象的代码写在getObject()方法当中(FactoryBean实现原理)?

        接口回调:在java体系当中,接口+反射什么都能做,本质上是一个接口回调,在Spring的底层代码中,通过id值获取ConnectionFactoryBean类的对象,进而判断是不是 BeanFactory接口的实现类(InstanceOf),如果是的话,Spring按照接口约定,调用getObject方法获取Connection对象,返回Connection对象

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP


        为什么说Spring创建的复杂对象都是懒加载的?
        Spring对于复杂对象的创建是懒加载的,使用FactoryBean创建复杂对象,在spring容器进行创建的时候只会先创建实现了FactoryBean这个类的对象,当getBean的时候才会有Spring的接口回调,获取复杂对象并进行返回,所以这是懒加载的

6:Factorybean总结

         Spring当中创建复杂对象的一种方式,也是spring原生提供的,后续我们讲整合其他框架时会大量应用BeanFactory这个接口的形式

三:实例工厂

1:为什么使用实例工厂

        避免Spring框架的侵入,使用Spring框架进行复杂框架开发的时候,如果使用beanFactory进行开发的,必须使用Spring提供的BeanFactory接口,这样日后离开Spring的话,那么久没有什么意义了

        应用实例工厂创建对象,主要是为了整合遗留系统,遗留系统中一些复杂对象的创建已经写好了,而且提供的是class文件不是java文件,这种情况处理的话,就是使用BeanFactory已经没办法了

2:实例工厂编码

class ConnectionFactory{
    public Connection getConnection(){
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/student", "root", "root");
        return connection;
    }
}
    <bean id="connFactory" class="com.pactera.spring.factorybean.ConnectionFactroy"></bean>
    <bean id = "conn" factory-bean="connFactory" factory-method="getConnection"/>


四:静态工厂

        实例工厂需要先创建实例工厂的对象,静态工厂当中直接类名.方法名进行调用就可以了,二者都是为了避免Spring的侵入,为了整合遗留的资源,以上就是Spring创建复杂对象的三种方式

1:配置文件上有些区别

    <!--静态工厂不需要创建对象,直接类名调用就完事了,用的比较少。使用的时候通过getBean("conn")获取的就是这个复杂对象。-->
    <bean id = "conn" class="com.pactera.spring.factorybean.StaticConnectionFactory" factory-method="getConnection"/>

2:Spring工厂创建对象的总结

基于FactoryBean、实例工厂、静态工厂创建Spring中的复杂对象-LMLPHP

11-29 14:45