spring-day02
1、bean的上面周期
大体上分为:
- 通过构造器创建 bean 实例(无参数构造)
- 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
- 调用 bean 的初始化的方法(需要进行配置初始化的方法)
- bean 可以使用了(对象获取到了)
- 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
生命周期的演示:
实体类:
public class Cycle {
private String time;
public Cycle() {
System.out.println("第一步:调用无参构造创建bean的实例");
}
public void setTime(String time) {
this.time = time;
System.out.println("第二步:为属性设置值");
}
/**
* 初始化bean对象
*/
public void initMethod(){
System.out.println("第三步:执行初始化的方法");
}
/**
* 销毁bean对象
*/
public void destroyMethod(){
System.out.println("第五步:执行销毁的方法");
}
}
xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
用于测试生命周期
-->
<bean class="com.day02.entity.Cycle" id="cycle" init-method="initMethod" destroy-method="destroyMethod">
<property name="time" value="2021-12-17"></property>
</bean>
</beans>
测试:
@Test
public void cycleTest(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
Cycle cycle = context.getBean("cycle", Cycle.class);
System.out.println("第四步:获取创建bean的实例对象");
// 手动让bean实例销毁
context.close();
}
结果:
第一步:调用无参构造创建bean的实例
第二步:为属性设置值
第三步:执行初始化的方法
第四步:获取创建bean的实例对象
第五步:执行销毁的方法
如果添加了后置处理器的话,那么生命周期就有七步,另外两步在调用bean的初始化方法的前后。如果我们在xml配置文件中添加了关于创建实现BeanPostProcessor接口的类的bean实例时,那么配置文件中的所有bean实例都会自动识别。
作为后置处理器的类:
public class Mybean implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化前调用");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后调用");
return bean;
}
}
实体类:
public class Cycle {
private String time;
public Cycle() {
System.out.println("第一步:调用无参构造创建bean的实例");
}
public void setTime(String time) {
this.time = time;
System.out.println("第二步:为属性设置值");
}
/**
* 初始化bean对象
*/
public void initMethod(){
System.out.println("第三步:执行初始化的方法");
}
/**
* 销毁bean对象
*/
public void destroyMethod(){
System.out.println("第五步:执行销毁的方法");
}
}
xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 用于测试后置处理器 -->
<bean class="com.day02.entity.Cycle" id="cycle" init-method="initMethod" destroy-method="destroyMethod">
<property name="time" value="2021-12-17"></property>
</bean>
<!-- 用于测试后置处理器,观察配置文件中的所有bean是否都调用了配置处理器的方法-->
<bean class="com.day02.entity.Processor" id="processor" init-method="initMethod" destroy-method="destroyMethod">
<property name="otherTime" value="2021-12-17"></property>
</bean>
<!-- 用于测试后置处理器,观察配置文件中的所有bean是否都调用了配置处理器的方法-->
<bean class="com.day02.entity.Cat" scope="prototype" id="cat">
<property name="catName" value="Jack"></property>
<property name="weight" value="10.2"></property>
</bean>
<!--
配置后置处理器:因为在MyBean实现了BeanPostProcessor接口,
此时只要创建bean实例,系统就是识别为后置处理器
1: 在此配置文件的对象都会调用后置处理器中的
postProcessBeforeInitialization和postProcessAfterInitialization方法
-->
<bean class="com.day02.bean.Mybean" id="mybean"></bean>
</beans>
测试:
@Test
public void cycleTest(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("bean2.xml");
Cycle cycle = context.getBean("cycle", Cycle.class);
System.out.println("第四步:获取创建bean的实例对象");
// 手动让bean实例销毁
context.close();
}
结果:
第一步:调用无参构造创建bean的实例
第二步:为属性设置值
初始化前调用
第三步:执行初始化的方法
初始化后调用
第四步:获取创建bean的实例对象
第五步:执行销毁的方法
2、自动装配 autowire
autowire:自动注入
- byName:根据属性名称注入(在Emp中属性Dept的名称为dept,这时会识别id为dept的bean实例)
- byType:根据类型注入(在Emp中dept属性的类型为Dept,这时就会根据Dept类型进行匹配,如果有多个类型相同的bean实例,那么系统就会提示错误)
这里用前面的部门Dept和员工Emp类作为实体类进行解释:
实体类:
public class Dept {
private String deptName;
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "Dept{" +
"deptName='" + deptName + '\'' +
'}';
}
}
public class Emp {
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp{" +
"dept=" + dept +
'}';
}
}
xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
autowire:自动注入
byName:根据属性名称注入(在Emp中属性Dept的名称为dept,这是会识别id为dept的bean实例)
-->
<bean class="com.day02.autowire.Dept" id="dept">
<property name="deptName" value="研发部"></property>
</bean>
<bean class="com.day02.autowire.Dept" id="dept2">
<property name="deptName" value="产品融资部"></property>
</bean>
<!--
使用byName进行自动装配
-->
<bean class="com.day02.autowire.Emp" id="emp" autowire="byName">
<!--
<property name="dept" ref="dept"></property>:用自动装配取代
-->
</bean>
<!--
使用byType进行自动装配:
在这个配置文件中会提示错误,因为有多个类型为Dept的bean,所以无法识别
<bean class="com.day02.autowire.Emp" id="emp2" autowire="byType"></bean>
-->
</beans>
测试:
public class AutoWireTest {
/**
* 测试byName
*/
@Test
public void byNameTest(){
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Emp emp = context.getBean("emp", Emp.class);
System.out.println(emp);
}
/**
* 测试byType
*/
@Test
public void byTypeTest(){
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Emp emp = context.getBean("emp2", Emp.class);
System.out.println(emp);
}
}
byName的测试结果:
Emp{dept=Dept{deptName='研发部'}}
byType的测试也很简单,就不演示了。
3、外部文件的注入
比如我们注入连接数据库的properties文件
注意:注入外部文件时,要添加context名称空间。
通过<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
导入jdbc.properties文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--
注入外部文件,需要引入context名称空间
-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="driverClassName" value="${prop.driverClass}"></property>
<property name="url" value="${prop.url}"></property>
<property name="username" value="${prop.userName}"></property>
<property name="password" value="${prop.password}"></property>
</bean>
</beans>
写这个文章主要是用于自己对知识点的梳理,当然也有想让各位跟我一样的小白参考,作者学识浅薄,有可能有错误,所以欢迎纠错,一起学习讨论,一起进步。