目录
什么是复杂对象?
简单对象:直接通过new的方式可以直接创建的。Person per = new Person();
复杂对象:不能直接通过new构造方法来创建的。
例如:Connection对象,SqlSessionFactory对象。
spring工厂创建复杂对象的3种方式:
1,实现spring提供的FactoryBean接口。
public class ConnectionFactory implements FactoryBean<Connection> {
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获得对象的代码
@Override
public Connection getObject() {
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//获得对象的class类型
@Override
public Class<?> getObjectType() {
return Connection.class;
}
//默认是true,表示获取的是单例
// 是否是单例对象
@Override
public boolean isSingleton() {
return false;
}
}
XML文件中:
<bean id="conn" class="begin.ConnectionFactory"></bean>
test代码:
/**
* 测试:创建复杂对象
*/
@org.junit.Test
public void test4(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection conn = (Connection) ctx.getBean("conn");
System.out.println(conn);
}
结果:
细节:Connection对象是不可公用的,而SqlSessionFactory是可以公用的。
配置文件中:如果使用和普通对象一样的配置方法,返回的就是复杂对象。若想要原来的对象,就要getBean("&conn").就会返回原来的那个类的对象。而不是由那个类创建的对象。
spring如何实现的?(明明我写的是得到class类的方法,给我的确是这个类创建的对象)。
原因: if(bean instanceof FactoryBean) return bean.getObject();
总结:spring创建复杂对象的一种方式,spring原生提供,spring衍生框架中,大量应用了FactoryBean接口。
2,实例工厂:
避免了spring框架的侵入;整合遗留系统(有class文件,而源码没有或者不能轻易修改)。
顾名思义:将工厂实例化,创建对象。
例如:
public class ConectionFactory1 {
public Connection getObject() {
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
XML文件中:
<bean id="connFactory" class="begin.ConectionFactory1"></bean>
<!-- 指定工厂对象,工厂得到对象方法-->
<bean id="conn" factory-bean="connFactory" factory-method="getObject"></bean>
结果:
总结:返回对象类不需要指定class,需要指定factory-bean和factory-method。
3,静态工厂
创建复杂对象是个静态工厂类,创建方法是静态方法。
public class ConectionFactory1 {
public static Connection getObject() throws ClassNotFoundException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
XML文件中:
<bean id="conn" class="begin.ConectionFactory1" factory-method="getObject"></bean>
结果:
spring控制对象的创建次数:
spring为什么要控制对象的创建次数呢?
比如所一个UserService只需要一个,一个UserDao也只需要一个(因为实现的功能是一样的,过多的会产生更大内存开销和冗余)。
如何控制:
1,实现FactoryBean接口后,之中有一个isSingleton方法。就是制定创建的对象是否是单例(即自始至终得到的对象只有一个)。return true。即可。
2,在XML文件bean标签中有一个scope属性,一个是prototype(原型表示创建多个一样的),一个是singleton(单例)。
好处:节省不必要的内存开销。
什么样的对象只创建一次呢?
各种dao和service。SqlSessionFactory和DispatchServlet(springMVC)的各种重量级资源(肯定都是线程安全的)。