Spring工厂创建复杂对象
时间:2022-07-24
本文章向大家介绍Spring工厂创建复杂对象,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
什么是复杂对象
复杂对象是指无法使用 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&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&&useSSL=false", "root", "root");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
}
在配置文件上略有区别:
<bean class="edu.lsu.factorybean.StaticConnectionFactory" id="staticConnectionFactory" factory-method="getConnection"/>
静态工厂不需要创建对象就能调用方法,所以直接使用标签的属性即可。
- Android O中对TEE加解密算法的新要求
- storm 原理简介及单机版安装指南
- Python Tips, Tricks, and Hacks
- 英特尔放出Linux微代码以修复Meltdown和Spectre漏洞
- python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域
- Linux SSH密码暴力破解技术及攻防实战
- 西部数据NAS设备被曝存在硬编码后门和未授权文件上传高危漏洞
- Hive & Performance 学习笔记
- 任意用户密码重置(一):重置凭证泄漏
- linux 系统监控、诊断工具之 top 详解
- 一个二进制POC的诞生之旅CVE-2018-0802
- 远程RPC溢出EXP编写实战之MS06-040
- 浮点数加法引发的问题:浮点数的二进制表示
- 新手科普 | MySQL手工注入之基本注入流程
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 我扒了半天源码,终于找到了Oauth2自定义处理结果的最佳方案!
- python 解决多核处理器算力浪费的现象
- python实现单例模式的5种方法
- java序列化和序列化ID的作用
- python函数式编程
- 让Vim打造成强大的IDE,附_vimrc的配置和使用
- python 中面向切面编程AOP和装饰器
- HashMap&ConcurrentHashMap&HashTable
- python中的垃圾回收机制
- python中值传递还是引用传递?
- 基于Docker+Jenkins+Git的集成开发环境搭建
- python 函数的本质理解
- centOS(离线) off-line install docker-ce
- Java 工厂 Simple Factory&Factory&Abstract Factory
- python 性能的优化