首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring工厂创建复杂对象

Spring工厂创建复杂对象

作者头像
wsuo
发布2020-09-10 10:22:55
6500
发布2020-09-10 10:22:55
举报
文章被收录于专栏:技术进阶之路技术进阶之路

什么是复杂对象

复杂对象是指无法使用 new 关键字直接创建的对象,比如在使用数据库连接的时候,我们需要用如下的方式创建对象:

Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useSSL=false", "root", "root");

再比如在使用 MyBatis 时要获取 SQLSessionFactory 也是不能使用 new 直接创建的。

Spring 工厂创建复杂对象的3种方式

1. FactoryBean 接口

Spring为我们提供了一个 FactoryBean 接口,我们可以实现该接口,并重写方法来创建复杂对象。

public class MyFactoryBean implements FactoryBean<Connection> {
    
    // 用于书写创建复杂对象
    @Override
    public Connection getObject() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useSSL=false", "root", "root");
    }

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

	// 是否单例
    @Override
    public boolean isSingleton() {
        return false;
    }
}

同时我们需要将该类加入到 Spring 容器中。

<bean class="edu.lsu.factorybean.MyFactoryBean" id="conn"/>

如果 class 中指定的类型是 FactoryBean 接口的实现类,那么通过 id 值获取的是这个类所创建的复杂对象。

ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection conn = ac.getBean("conn", Connection.class);
System.out.println("conn = " + conn);

输出:
conn = com.mysql.jdbc.JDBC4Connection@4c40b76e

如果我们就像获取 FactoryBean 类型的变量,可以这样写:

ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml");
MyFactoryBean acBean = ac.getBean("&conn", MyFactoryBean.class);
System.out.println("acBean = " + acBean);

输出:
acBean = edu.lsu.factorybean.MyFactoryBean@5fcd892a

在 id 前面加上一个 & 号。

如果我们设置 isSingleton 的返回值为 true,那么多次获取的对象都是同一个,如果返回 false 则每次都会创建一个新的对象。

那么为什么 Spring 要定一个 FactoryBean 接口呢?

  • 正如一句谚语所说:“接口加反射,什么都能做。” FactoryBean 接口就是一个接口回调。

FactoryBean 的工作原理:

  • Spring 首先从配置文件中通过 conn 获取 bean 对象,然后判断 instance(FactoryBean) 子类。
  • 调用 getObject() 方法,创建复杂对象。

2. 实例工厂

由于实现 FactoryBean 接口会引起 Spring 框架的侵入,即一旦我们离开了 Spring,那么代码将不能使用。

至于为什么叫做实例工厂是因为只有再创建实例之后才能调用它的方法。

public class ConnectionFactory {
    public Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;useSSL=false", "root", "root");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

同时需要在配置文件中配置如下信息:

<bean class="edu.lsu.factorybean.ConnectionFactory" id="connectionFactory"/>
<bean id="connection" factory-bean="connectionFactory" factory-method="getConnection"/>

3. 静态工厂

静态工厂和实例工厂的区别就在于实例工厂的方法是实例方法,而静态工厂的方法是静态的。

public class StaticConnectionFactory {
    public static Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp&useSSL=false", "root", "root");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

在配置文件上略有区别:

<bean class="edu.lsu.factorybean.StaticConnectionFactory" id="staticConnectionFactory" factory-method="getConnection"/>

静态工厂不需要创建对象就能调用方法,所以直接使用标签的属性即可。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是复杂对象
  • Spring 工厂创建复杂对象的3种方式
    • 1. FactoryBean 接口
      • 2. 实例工厂
        • 3. 静态工厂
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档