06-Spring复杂对象的创建
程序员文章站
2022-05-29 14:46:32
...
上一篇:05-Spring反转控制IOC 与 依赖注入DI概念https://blog.csdn.net/fsjwin/article/details/109411172
什么是复杂对象?
不能通过new的方式创建出来的对象就是复杂对象。
下面试对简单对象和复杂对象的说明,这样的话对简单对象和复杂对象就有了具体的认识。这里非常重要。学习一定要有调性,有节奏,这样掌握起来就得心应手。
对于复杂对象的创建无法使用new的方式创建了。但是此路不通,别路通,下面介绍三种创建复杂对象的方式:
- 1.FactoryBean
- 2.实例工厂
- 3.静态工厂
1.FactoryBean创建复杂对象
以创建Connection为例。
- 引入mysql的驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
- 创建MyConnectionFacoryBean实现FactoryBean接口
package base.comobjectcreate.factorybean;
import org.springframework.beans.factory.FactoryBean;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author yuhl
* @Date 2020/11/1 9:50
* @Classname MyFacoryBean
* @Description FactoryBean创建复杂对象
*/
public class MyConnectionFacoryBean implements FactoryBean<Connection> {
//创建对象
@Override
public Connection getObject() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("mysql://localhost:3306/yuhl", "root", "root");
return connection;
}
//返回创建对象的类型
@Override
public Class<?> getObjectType() {
return Connection.class;
}
/**
*
* @return
* 是否是单利模式 true:单利模式
*/
@Override
public boolean isSingleton() {
return false;
}
}
- 配置文件
返回的就是Connection对象了。
<bean id="conn" class="base.comobjectcreate.factorybean.MyConnectionFacoryBean"/>
- 测试获得Connect对象
@Test
public void test11() {
System.out.println("test9-------------------");
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection connection = (Connection) ctx.getBean("conn");
Connection connection2 = (Connection) ctx.getBean("conn");
System.out.println(connection);
System.out.println(connection2);
}
- 怎么获得MyConnectionFacoryBean对象?
&conn的使用
/**
* &conn 获取 MyConnectionFacoryBean对象
*/
@Test
public void test12() {
System.out.println("test9-------------------");
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
MyConnectionFacoryBean connection = (MyConnectionFacoryBean) ctx.getBean("&conn");
System.out.println(connection);
}
- 对于Connection对象,没有应该都是不同的。所以不能使用单利模式
/**
*
* @return
* 是否是单利模式 true:单利模式
*/
@Override
public boolean isSingleton() {
return false;
}
- MyConnectionFacoryBean类中的用户名和密码及连接怎么解耦
此类对这三个有依赖,那么有依赖就可以注入,所以我们的思想是注入进去。
MyConnectionFacoryBean.java 定义成员变量
package base.comobjectcreate.factorybean;
import org.springframework.beans.factory.FactoryBean;
import java.security.spec.PSSParameterSpec;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author yuhl
* @Date 2020/11/1 9:50
* @Classname MyFacoryBean
* @Description FactoryBean创建复杂对象
*/
public class MyConnectionFacoryBean implements FactoryBean<Connection> {
String driver;
String url;
String username;
String password;
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 String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
//创建对象
@Override
public Connection getObject() throws Exception {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
//返回创建对象的类型
@Override
public Class<?> getObjectType() {
return Connection.class;
}
/**
*
* @return
* 是否是单利模式 true:单利模式
*/
@Override
public boolean isSingleton() {
return false;
}
}
配置文件修改:
<bean id="conn" class="base.comobjectcreate.factorybean.MyConnectionFacoryBean">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/spring?useSSl=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
正常测试通过。
- jdbc:mysql://127.0.0.1:3306/spring?useSSl=false 为什么要加useSSl=false
myslq高版本默认使用ssl加密,如果不主动关闭的话,日志会有警告,但是不影响使用。
- 原理解析(简易版)
当使用
MyConnectionFacoryBean connection = (MyConnectionFacoryBean) ctx.getBean("&conn");
创建对象的时候,spring层会调用object.instanceOf()方法,看当前对象是不是FacoryBean对象(实现类),如果是,则调用其getObject()方法返回返回值。
当然会校验isSinglton是否为true,返回单利或者非单利对象。
2.实例工厂创建复杂对象
FactoryBean有侵入。
整合遗留系统。
对于已经有的class文件,仅通过配置的方式创建conn对象。
- 已经拿到的class文件的源码,这个类很有可能就是个大框架中提供好的
package base.comobjectcreate.factorybean;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author yuhl
* @Date 2020/11/1 10:59
* @Classname ConnectionFactory
* @Description 已经拥有的类
*/
public class ConnectionFactory {
public Connection getConnection(){
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/spring", "root", "root");
return connection;
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
}
- 配置文件
<bean id="connectionFactory" class="base.comobjectcreate.factorybean.ConnectionFactory"/>
<bean id="connection" factory-bean="connectionFactory" factory-method="getConnection"/>
- 测试
/**
* 实例工厂
* 为什叫:实例工厂呢?因为需要先new ConnectionFactory(),获得工厂的实例,然后调用new ConnectionFactory().getConnection()方法,所以叫实例工厂
*/
@Test
public void test13() {
System.out.println("test9-------------------");
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection connection = (Connection) ctx.getBean("connection");
System.out.println(connection);
}
为什叫:实例工厂呢?
- 因为需要先new ConnectionFactory(),获得工厂的实例,然后调用new ConnectionFactory().getConnection()方法,所以叫实例工厂
3.静态工厂创建复杂对象
- 静态工厂和实例工厂唯一的区别就是getConnect()方法是静态的。随之配置有所不同
StaticConnectionFactory.java
package base.comobjectcreate.factorybean;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author yuhl
* @Date 2020/11/1 10:59
* @Classname ConnectionFactory
* @Description 静态工厂,静态方法
*/
public class StaticConnectionFactory {
public static Connection getConnection(){
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/spring", "root", "root");
return connection;
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
}
- 配置文件
<!--静态工厂-->
<bean id="staticConnectionFactory" class="base.comobjectcreate.factorybean.StaticConnectionFactory" factory-method="getConnection"/>
- 测试
/**
* 静态工厂
*/
@Test
public void test14() {
System.out.println("test9-------------------");
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection connection = (Connection) ctx.getBean("staticConnectionFactory");
System.out.println(connection);
}
4.总结
对接第三方框架的时候,你没的选择,人家是什么你就使用什么样的方式去使用。
但是如果是新项目建议使用FactoryBean的方式。
下一篇:07-Spring对象的创建次数 singleton|prototype https://blog.csdn.net/fsjwin/article/details/109427054