网站首页 > 技术文章 正文
1.IOC、DI、复杂对象 相关概念
1.1 控制反转 IOC
控制反转:把对于成员变量赋值的控制权,从代码中反转(转移)到Spring工厂和配置文件中完成
好处:解耦合
底层实现:工厂设计模式
1.2 依赖注入 DI
注入:通过Spring的工厂及配置文件,为对象(bean,组件)的成员变量赋值(get set)
依赖注入:当一个类需要另一个类的时候,就意味着依赖,,一旦出现依赖,就可以把另一个类作为本类的成员变量,最终通过Spring配置文件进行注入(赋值)
1.3 复杂对象
简单对象:可以直接通过new 构造方法创建的对象(Person)
复杂对象:不能直接通过new 构造创建的对象(sqlSessionFactory...),重量级资源
2.创建复杂对象的三种方式
2.1 FactoryBean接口
步骤:实现FactoryBean工厂,实现三个方法,在spring配置文件中配置
重点看后面实现的那三个方法
写一个ConnectionFactoryBean,实现接口:
2.1.1 依赖注入的体会
Class.forName(driverClassName);
Connection conn = DriverManager.getConnection(url,username,pwd);
创建Connection需要三个属性,这时就产生了依赖,通过配置注入到属性中,再进行使用,将程序的耦合度降低。
package zyc.stu.Spring5_34_44.FactoryBeanTest;
import java.sql.Connection;
import java.sql.DriverManager;
import org.springframework.beans.factory.FactoryBean;
/**
* @author zhuZiGe_
* @create 2020-09-10-9:30
*/
public class ConnectionFactoryBean implements FactoryBean<Connection> {
private String driverClassName;
private String url;
private String username;
private String pwd;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
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 getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
//实现三个方法
public Connection getObject() throws Exception {
Class.forName(driverClassName);
Connection conn = DriverManager.getConnection(url,username,pwd);
return conn;
}
public Class<?> getObjectType() {
return Connection.class;
}
public boolean isSingleton() {
return false;
}
}
xml文件配置:
<bean id="conn" class="zyc.stu.Spring5_34_44.FactoryBeanTest.ConnectionFactoryBean">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springdemo?useSSL=false"/>
<property name="username" value="root"/>
<property name="pwd" value="root"/>
</bean>
测试:
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection conn = (Connection) context.getBean("conn");
System.out.println(conn);
}
细节:
- context.getBean("conn") 获得的是FactoryBean接口的泛型指定类:自动调用了重写的第一个方法getObject(),得到的是内部创建的复杂对象
- isSingleton():控制了此复杂对象的创建次数
- 返回false:不是单例,每次创建新的对象
- 返回true:是单例,拿着上次创建的对象
- 问题:什么时候返回ture?
- 根据需要,例如Connection,不能共用,每次都要创建新的连接,而SqlSessionFactory耗资源,只要一个就够了
2.2 实例工厂
用途1:避免Spring框架的侵入(FactoryBean接口导致整个系统依赖于Spring)
用途2:整合遗留系统:
从现有的基础继续开发,没有源文件.java可供修改,只有编译好的.class文件时
没有源文件就无法实现FactoryBean接口
例:ConnectionFactory中是用的原始的方法实现复杂对象的创建,想得到复杂对象,必须实例化ConnectionFactory再调用getConnection方法,这时只需要在配置文件中集成这个遗留就行。
下面模拟一个遗留下来的实例:
先创建遗留实例的bean,将其纳入Spring管理,再创建新的bean,指明bean和想要调用的方法。
package zyc.stu.Spring5_34_44.FactoryBeanTest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @author zhuZiGe_
* @create 2020-09-10-12:35
*/
public class ConnectionFactory {
public Connection getConnection(){
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/springdemo?useSSL=false","root","root");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return conn;
}
}
在xml文件中配置:我只想拿你内部那个方法获取复杂对象而已
<bean id="connFactory" class="zyc.stu.Spring5_34_44.FactoryBeanTest.ConnectionFactory"></bean>
<bean id="connSL" factory-bean="connFactory" factory-method="getConnection"/>
测试:
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
Connection connSL = (Connection) context.getBean("connSL");
System.out.println(connSL);
}
2.3 静态工厂
- 静态工厂和实例工厂大致相同,只不过工厂中的方法是静态的。
- 配置文件中,不用创建静态工厂的bean再去引用,直接使用class属性指定类,再指定调用的方法。
将上面的类名ConnectionFactory改为StaticConnectionFactory,并在方法上标记static,主要看xml文件中如何配置
<bean id="staticConnectionFactory" class="zyc.stu.Spring5_34_44.FactoryBeanTest.StaticConnectionFactory" factory-method="getConnection"/>
3.控制对象的创建次数
3.1 控制简单对象的创建次数
在配置文件中进行配置:
sigleton:只会创建?次简单对象,默认值;
prototype:每?次都会创建新的对象;
3.2 控制复杂对象的创建次数
通过isSingleton()方法控制:参考本文 2.1
public boolean isSingleton() { return true/false; }
3.3 如果是实例工厂或者静态工厂,没有 isSingleton ?法,与简单对象一样通过 scope 控制。
3.4 为什么要控制对象的创建次数
好处:节省不必要的内存浪费。
什么样的对象只创建?次?
- 重量级的、可以被共用的、线程安全的…
SqlSessionFactory | DAO | Service
什么样的对象每?次都要创建新的?
- 不能被共用的,线程不安全的…
Connection | SqlSession | Session
4.结尾
本文到这里就结束了,感谢看到最后的朋友,都看到最后了,点个赞再走啊,如有不对之处还请多多指正。
猜你喜欢
- 2024-10-15 BATJ面试必会之 Spring 篇(30题) 面试spring的面试题
- 2024-10-15 Spring知识点提炼 spring题
- 2024-10-15 springmvc的核心是啥,请求的流程怎么处理,控制反转怎么实现
- 2024-10-15 spring源码分析——spring大纲 spring源码分析和总结简书
- 2024-10-15 Spring思维导图,让Spring不再难懂(ioc篇)
- 2024-10-15 Spring框架介绍及使用 spring框架的使用步骤
- 2024-10-15 架构师必知必会:Java内置的控制反转机制-Service Provider
- 2024-10-15 轻松理解 Spirng IoC/控制方向反转
- 2024-10-15 什么是控制反转(ioc),通过解释总结告诉你
- 2024-10-15 搞透IOC,Spring IOC看这篇就够了
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)