🍹🍭🎊🎊️️🚸🛳️
bean生命周期
生命周期:从创建到消亡的完整过程
➠***bean生命周期***:bean(对象)从创建到销毁的整体过程
➠***bean生命周期控制***:在bean创建后到销毁前做一些事情
🛳️***通过Bean的配置控制其生命周期***
<!-- init-method:初始化的方法 destroy-method:销毁的方法 -->
<bean id="bookDao" name="bookDao2 bookDao3 " class="com.GY.dao.impl.BookDaoImpl" init-method="M1" destroy-method="M2"/>
package com.GY.dao.impl;
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("book dao save.......");
}
//表示Bean初始化对应的操作(方法名任意)
public void M1(){
/*按照业务写
eg:初始化时加载一些资源或者读取一些文件
*/
System.out.println("初始化前......");
}
//表示Bean销毁前对应的操作(方法名任意)
public void M2(){
System.out.println("销毁前......");
}
}
结果:
🚸🚸🚸
?为何销毁操作M2没有执行 ?
程序是运行在JAVA虚拟机中的,虚拟机启动后,IOC加载了配置也启动,Bean初始化,拿到Bean执行完后,下一个动作为虚拟机退出 ,没有给Bean销毁的机会
🎊🎊️️🎊🎊️️
实现销毁操作
🍭方式一:(手工关闭容器,在虚拟机退出之前将容器关闭)
这是一种比较暴力的方式!!!
🚸🚸🚸
🍭方式二:(注册关闭钩子,容器启动后先加一个标记,虚拟机退出之前先关闭容器再退出)
🍹🍹🍹🍹🍹🍹🍹
这两种方式在实际开发中均不用写(较乱),Spring通过接口的方式实现
package com.GY.service.impl;
import com.GY.dao.impl.BookDao;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void save(){
System.out.println("book service save.....");
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
//在属性值设置后运行
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(3222222);
}
//
@Override
public void destroy() throws Exception {
System.out.println(1111111);
}
}
Bean在初始化经历的阶段:
●初始化容器
1、 创建对象(内存分配)
2、执行构造方法
3、执行属性注入(set操作)
4、执行bean初始化方法:
●使用bean
1、执行业务操作
●关闭/销毁容器
1、执行bean销毁方法
🍹🍭🎊🎊️️🚸🛳️
依赖注入方式
🚸🚸🚸
向一个类中传递数据的方式有几种?
➠普通方法(set方法)
➠构造方法
☞ 思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
●引用类型
●简单类型(基本数据类型与String)
🎊🎊🎊
☞依赖注入方式
●setter注入(简单/引用类型)
◆在bean中定义引用类型并提供可访问的set方法
◆配置中使用property标签value属性注入简单数据类型
配置:
<bean id="bookDao" class="com.GY.dao.impl.BookDaoImpl" >
<property name="count" value="10"/>
<property name="database" value="mysql"/>
</bean>
●构造器注入(简单/引用类型)☞☞☞☞☞☞☞与形参名耦合度较高
<!--构造器注入的name不可随意写,其为构造方法中的形参名-->
<bean id="bookService" class="com.GY.service.impl.BookServiceImpl" >
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.GY.dao.impl.BookDaoImpl" >
<constructor-arg name="count" value="10"/>
<constructor-arg name="database" value="mysql"/>
</bean>
☟☟☟☟☟☟☟☟☟☟☟☟☟☟☟
解决参数类型重复问题(使用位置解决),并且解决形参耦合
<bean id="bookDao" class="com.GY.dao.impl.BookDaoImpl" >
<constructor-arg index="0" value="10"/>
<constructor-arg index="1" value="mysql"/>
<constructor-arg index="2" value="MM"/>
</bean>
public class BookDaoImpl implements BookDao{
private int count;
private String database;
private String MM;
public BookDaoImpl(int count, String database,String MM) {
this.count = count;
this.database = database;
this.MM=MM;
}
}
依赖注入方式选择
1.强制依赖使用构造器(构造器注入是必写的,否则对象创建不成功,配置文件也将会报错)进行 ,使用setter注入(可选)进行有概率不进行注入导致null对象出现
2.可选依赖使用setter注入进行 ,灵活性强
3.Spring框架倡 导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
4.如果有必要可以两者同时使用, 使用构造 器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
5.实际开发过程中还要根据实际情况分析, 如果受控对象没有提供setter方法就必须使用构造器注入
6.自己开发的模块推荐使用setter注入
依赖自动装配
➠***自动装配***:IOC容器根据bean所依赖的资源在容器中自动查找并注入到bean的过程
➠***自动装配的方式(4种)***
●按类型 (常用)
<bean id="bookService" class="com.GY.service.impl.BookServiceImpl " autowire="byType" />
●按名称
<!--被注入的bean的id(此处为bookDao)需与set方法的形参名一致-->
<bean id="bookDao " class="com.GY.dao.impl.BookDaoImpl" >
<bean id="bookService" class="com.GY.service.impl.BookServiceImpl " autowire="byName" />
●按构造方法(不推荐使用)
●不启用自动装配
➠***依赖自动装配特征***
●自动装配用于引用类型依赖注入 ,不能对简单类型进行操作
●使用按类型装配时( byType )必须保障容器中相同类型的bean唯一, 推荐使用
●使用按名称装配时( byName )必须保障容器中具有指定名称的bean ,这种形式并不好,因为变量名与配置耦合,不推荐使用
●自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
集合注入
➠数组
➠List
➠Set
➠Map
➠Properties
//实现类
public class BookDaoimpl implements BookDao {
private int[]array;
private List<String>list;
private Set<String>set;
private Map<String,String>map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println("book........");
System.out.println("①"+array);
System.out.println("②"+list);
System.out.println("③"+set);
System.out.println("④"+map);
System.out.println("⑤"+properties);
}
}
<!--配置文件-->
<bean id="BookDao" class="com.GY.BookDaoimpl" autowire="byType" >
<property name="array" >
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<property name="list">
<list>
<value>GY,ghg,gf</value>
<value>buyuvycy</value>
</list>
</property>
<property name="map">
<map>
<entry key="一" value="1"/>
<entry key="二" value="2"/>
</map>
</property>
<property name="properties">
<props>
<prop key="1">一</prop>
<prop key="2">二</prop>
</props>
</property>
</bean>
结果