复杂对象:不能直接通过 new 构造方法创建的对象

Spring创建复杂对象的三种方式:

  • FactoryBean 接口
  • 实例工厂
  • 静态工厂

FactoryBean 接口

1、实现 FactoryBean 接口
复杂对象 - 图1

  1. public class MyFactoryBean implements FactoryBean {
  2. @Override
  3. public Object getObject() throws Exception {
  4. // 用于书写创建复杂对象的代码并把复杂对象作为方法的返回值返回
  5. return null;
  6. }
  7. @Override
  8. public Class<?> getObjectType() {
  9. // 返回所创建复杂对象的Class对象
  10. return null;
  11. }
  12. @Override
  13. public boolean isSingleton() {
  14. // 根据所创建对象是否为单例
  15. return false;
  16. }
  17. }

**
2、Spring 文件的配置

  1. <!-- 如果Class中的对象是 FactoryBean 的实现类,那么在 Spring 中通过 id 获得是这个类所创建得复杂对象 -->
  2. <bean id="bean" class="com.example.MyFactoryBean"/>

注意事项:

  1. context.getBean(“bean”):获得的是 FactoryBean 创建的复杂对象
    context.getBean(“&bean”):获得的是 FactoryBean 类型的对象
  2. isSingleton方法:返回true,为单例;返回 false,为多实例
    使用:根据对象特性,决定是否单例
    • SqlSessionFactory(重量级资源),返回 true
    • Connection(数据库连接),返回false
  3. 原理:反射 + 接口回调
    • 通过conn获得ConnectionFactoryBean类的对象,进而通过instanceof判断出是FactoryBean的实现类
    • Spring按照规定 getObject() -> Connection
    • 返回Connection

复杂对象 - 图2

实例工厂

实例工厂原因:

  1. 避免Spring工厂的侵入
  2. 整合遗留系统

步骤:
1、假设存在遗留的工厂类:

  1. public class ConnectionFactory {
  2. public Connection getConnection(){
  3. Connection connection = null;
  4. try{
  5. Class.forName("com.mysql.cj.jdbc.Driver");
  6. connection = DriverManager.getConnection("jdbc:mysql://localhost/mp?useSSL=false",
  7. "root",
  8. "root");
  9. } catch (ClassNotFoundException | SQLException e) {
  10. e.printStackTrace();
  11. }
  12. return connection;
  13. }
  14. }

2、在Spring配置文件中进行配置:即正常的创建步骤

  1. 先创建工厂实例:ConnectionFactory factory = new ConnectionFactory();
  2. 再调用工厂方法:factory.getConnection()
    1. <!-- 使用Spring管理工厂类 -->
    2. <bean id="connectionFactory" class="top.songfang.ConnectionFactory"/>
    3. <!-- 使用工厂类实例创建相应的bean -->
    4. <bean id="connection" factory-bean="connectionFactory" factory-method="getConnection"/>

    静态工厂

1、静态工厂
将上述的工厂类转换成 static ,因此在调用时直接可以使用工厂类名.工厂方法调用,即ConnectionFactory.getConnection()

2、Spring配置文件:

  1. <bean id="connection" class="top.songfang.ConnectionFactory" factory-method="getConnection"/>