Spring中复杂对象的创建方式:FactoryBean、实例工厂与静态工厂全解析
1.反转控制与依赖注入
控制:对于成员变量赋值的控制权
反转控制:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中完成
好处:解耦合
底层实现:工厂设计模式
依赖注入:
注入:通过Spring的工厂以及配置文件,为对象(bean、组件)的成员变量赋值
依赖注入:当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一类作为本类的成员变量,最终通过Spring的配置文件进行注入(赋值)。
2.Spring创建复杂对象
1.什么是复杂对象?
复杂对象:指的就是不能直接通过new 构造方法创建的对象
Connection
SqlSessionFactory
2.Spring工厂创建对象的三种方式
2.1FactoryBean接口
开发步骤
- 实现FactoryBean接口
@Override
public Connection getObject() throws Exception {
//用于书写创建复杂对象的代码 并把复杂对象作为方法的返回值
Class.forName("com.mysql.jdbc.Driver");
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/sky_take_out","root","123456");
return connection;
}
@Override
public Class<?> getObjectType() {
//返回 所创建对象的Class对象
return Connection.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
- Spring配置文件的配置
#如果Class指定的类型 是FactoryBean接口的实现类,那么通过id获得的是这个类
所创建的复杂对象 Connection
<bean id="connection" class="factoryBean.ConnectionFactoryBean"></bean>
- 细节
1.如果就想获得FactoryBean类型对象怎么办?
connection.getBean("&connection");
2.isSingleton方法
- 返回true 只会创建一次对象
- 返回false 每一次都会创建一个对象
根据对象的特点,决定是返回true(SqlSessionFactory) 还是false(Connection)(如果是true,公用一个对象的话 一个连接完成操作提交事务,另一个还没完成 可能就会出现并发问题)
3.mysql高版本连接创建时,需要指定SSL证书、解决问题方式:
url="jdbc:mysql//localhost:3306/数据库?useSSL=false"
4.依赖注入的体会
把ConnectionFactoryBean中依赖的4个字符串信息,进行配置文件的注入
好处:解耦合
<bean id="connection" class="factoryBean.ConnectionFactoryBean">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/sky_take_out?useSSL=false"></property>
<property name="password" value="123456"></property>
<property name="username" value="root"></property>
</bean>
FactoryBean的实现原理(简易版)
接口问题
1.为什么Spring规定FactoryBean接口实现 并且getObject()?
2.ctx.getBean("connection") 获得是复杂对象 Connection而没有获得ConnectionFactoryBean
Spring内部运行流程
1.通过conn 获得 ConnectionFactoryBean类的对象,进而通过instanceof 判断出FactoryBean接口的实现类
2.Spring安好规定 调用getObject()-->connection
3.返回Connection
FactoryBean总结
Spring中用于创建复杂对象的一种方式,也是Spring原生提供的,后续Spring整合其它框架,大量应用FactoryBean
2.2实例工厂
1.避免Spring框架的侵入
- 业务代码不需要直接依赖 Spring,而是通过工厂方法获取实例,这样即使不使用 Spring,代码仍然可以独立运行。
- 适用于对 Spring 侵入性敏感的场景,比如一些需要独立测试或可能会被迁移到非 Spring 运行环境的项目。
2.整合遗留系统
- 通过实例工厂模式,可以让 Spring 以兼容的方式管理这些遗留系统中的对象,而无需修改原有代码。
- 遗留系统的业务逻辑可以保持不变,而 Spring 只是用工厂的方式来管理这些对象
- 开发步骤
<bean id="connFactory" class="factoryBean.ConnectionFactory"></bean> <bean id="conn" factory-bean="connFactory" factory-method="getConnection"></bean>
2.3静态工厂
<bean id="staticConn" class="factoryBean.StaticConnetionFactory" factory-method="getConnection"></bean>