文章目录
反转控制
反转控制(IOC Inverse of Control)
1. 控制:对于成员变量赋值的控制权
2. 反转控制:把对于成员变量赋值的控制权,从代码反转(转移)到 Spring 工厂和配置文件中完成
3. 好处:解耦合
4. 底层实现:工厂设计模式
依赖注入
依赖注入(DI,Dependency Injection)
1. 注入:通过 Spring 的工厂及配置文件,为对象(bean,组件)的成员变量赋值
2. 依赖注入:当一个类需要另一个类的时候,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,通过Spring进行注入
3. 好处:解耦合
Spring工厂创建复杂对象
1、什么是复杂对象
1. 复杂对象:指的就是不能直接通过 new 构造方法创建的对象
Connection
SqlSessionFactory
2、Spring 工厂创建复杂对象的3种方式
2.1FactoryBean接口
开发步骤
1)实现 FactoryBean 接口
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 配置文件的配置
<!--注意: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
总结
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);