反转控制、依赖注入、创建复杂对象

反转控制

反转控制(IOC Inverse of Control)

1. 控制:对于成员变量赋值的控制权
2. 反转控制:把对于成员变量赋值的控制权,从代码反转(转移)到 Spring 工厂和配置文件中完成
3. 好处:解耦合
4. 底层实现:工厂设计模式

image-20200704211552151

依赖注入

依赖注入(DI,Dependency Injection)

1. 注入:通过 Spring 的工厂及配置文件,为对象(bean,组件)的成员变量赋值
2. 依赖注入:当一个类需要另一个类的时候,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,通过Spring进行注入
3. 好处:解耦合

image-20200704212854032

Spring工厂创建复杂对象

1、什么是复杂对象

image-20200705083913901

1. 复杂对象:指的就是不能直接通过 new 构造方法创建的对象
	Connection
	SqlSessionFactory
2、Spring 工厂创建复杂对象的3种方式
2.1FactoryBean接口
开发步骤

1)实现 FactoryBean 接口

image-20200705084414183

public class ConnectionFactoryBean  implements FactoryBean<Connection> {
    //用于书写创建复杂对象的代码
    public Connection getObject() throws Exception {
        String url = "jdbc:mysql://localhost:3306/dzf";
        String username = "root";
        String password = "root";
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, username, password);
        return connection;
    }

    public Class<?> getObjectType() {
        return Connection.class;
    }

    public boolean isSingleton() {
        return false;
    }
}

​ 2)Spring 配置文件的配置

image-20200705084858412

<!--注意:Class中指定的内容是FactoryBean接口的实现类,通过id获得的是这个实现类所创建的复杂对象-->
<bean id="conn" class="cf.duanzifan.factorybean.ConnectionFactoryBean"/>
public class Test3 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Connection conn = (Connection) applicationContext.getBean("conn");
        System.out.println(conn);//com.mysql.jdbc.JDBC4Connection@7a675056
    }
}
一些其他细节
  • 如果想获得 FactoryBean 类型的对象-----applicationContext.getBean("&conn");

    ConnectionFactoryBean conn = (ConnectionFactoryBean) applicationContext.getBean("&conn");
    System.out.println(conn);//cf.duanzifan.factorybean.ConnectionFactoryBean@59fd97a8
    
  • isSingleton 方法

    返回 true 只会创建一个复杂对象

    返回 false 每一次都会创建新的对象

    我们要根据对象的特点,决定返回true(SqlSessionFactory)还是 false(Connection)

  • 通过依赖注入来解耦合 connection 对象的创建(通过 Spring 中的 set 注入)

public class ConnectionFactoryBean  implements FactoryBean<Connection> {
    private String driver ;
    private String url ;
    private String username ;
    private String password ;

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    //用于书写创建复杂对象的代码
    public Connection getObject() throws Exception {

        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, username, password);
        return connection;
    }

    public Class<?> getObjectType() {
        return Connection.class;
    }

    public boolean isSingleton() {
        return false;
    }
}
<bean id="conn" class="cf.duanzifan.factorybean.ConnectionFactoryBean">
    <property name="driver" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/dzf"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</bean>
FactoryBean 的实现原理(简易版)
1. 接口回调
	Spring内部的运行流程
	1. 通过 conn 获得 ConnectionFactroyBean 类的对象,并且通过 instanceof 判断出是 FactoryBean 接口的实现类
    2. Spring 按照规定 getObject() 获得 connection 复杂对象
    3.返回 connection

image-20200705092313521

总结
1. Spring 中用于创建复杂对象的一种方式,也是 Spring 原生提供的,后续 Spring 整合其他框架时,会大量使用 FactoryBean。
2.2实例工厂
1. 避免 Spring 框架的侵入
2. 整合遗留系统

我们可能会遇到已经编写好的 ConnectionFactory

public class ConnectionFactory {
    Connection connection;
    public Connection getConnection (){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dzf","root","root");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}
//原先要想获得 conn ,且没有.java源代码,得通过.class获得
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = connectionFactory.getConnection();
System.out.println(connection);

我们怎么在配置文件中去用这个 ConnectionFactory

  • 开发步骤
<bean id="connFactory" class="cf.duanzifan.factroy.ConnectionFactory"></bean>
<bean id="con" factory-bean="connFactory" factory-method="getConnection"></bean>
//此时用 ConnectionFactory 获得复杂对象 connection
Connection connection = (Connection) applicationContext.getBean("con");
System.out.println(connection);
2.3静态工厂
public class ConnectionFactory {

    public static Connection getConnection (){
        Connection connection =null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dzf","root","root");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}
//原先要想获得 conn
Connection connection = ConnectionFactory.getConnection();
System.out.println(connection);
  • 开发步骤
<bean id="con" class="cf.duanzifan.factroy.ConnectionFactory" factory-method="getConnection"></bean>
//此时用 ConnectionFactory 获得复杂对象 connection
Connection connection = (Connection) applicationContext.getBean("con");
System.out.println(connection);

Spring 工厂创建对象总结

image-20200705100225305

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值