spring入门
1. Spring中Bean的生命周期
ApplicationContext Bean生命周期流程
ApplicationContext容器中,Bean的生命周期流程如上图所示,流程大致如下:
1.首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化,
2.按照Bean定义信息配置信息,注入所有的属性,
3.如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id,
4.如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory,
5.如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext,
6.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法,
7.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,
8.如果Bean配置了init-method方法,则会执行init-method配置的方法,
9.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,
10.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了
11.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,
12.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束
代码示例:
- bean类代码
package com.atguigu.configuration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @USER:
* @DATE: 2021-07-13
* @description:测试bean的生命周期
*/
public class BookBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean
, DisposableBean {
private String id;
private String name;
private String author;
public BookBean(){
System.out.println("BookBean构造方法被调用");
}
//1.set注入 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
public void setId(String id) {
System.out.println("1.setId被调用");
this.id = id;
}
public void setName(String name) {
System.out.println("1.setNames被调用");
this.name = name;
}
public void setAuthor(String author) {
System.out.println("1.setAuthor被调用");
this.author = author;
}
@Override
public String toString() {
return "BookBean{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
//2.调用BeanNameAware的setBeanName方法 设置bean的名字 此处传递的是Spring配置文件中Bean的ID
@Override
public void setBeanName(String s) {
System.out.println("2.调用BeanNameAware的setBeanName方法");
}
//3.调用BeanFactoryAware的setBeanFactory 设置Bean的工厂模式 传递的是Spring工厂本身(可以用这个方法获取到其他Bean)
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3.调用BeanFactoryAware的setBeanFactory方法");
}
//4.调用ApplicationContextAware的setApplicationContext方法 传入Spring上下文
// 以为ApplicationContext是BeanFactory的子接口,有更多的实现方法
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("4.调用ApplicationContextAware的setApplicationContext方法");
}
//6.调用调用InitizingBean的afterPropertiesSet方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("6.调用InitizingBean的afterPropertiesSet方法");
}
//7.调用初始化方法
public void myInit(){
System.out.println("7.调用定制的初始化方法");
}
//9.调用DispostbleBean的destroy
@Override
public void destroy() throws Exception {
System.out.println("9.调用DispostbleBean的destroy方法");
}
//10.调用定制的销毁方法
public void myDestroy(){
System.out.println("9.调用定制的销毁方法");
}
}
2.后置处理器代码:
package com.atguigu.configuration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @USER:
* @DATE: 2021-07-13
* @description:功能描述
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
//5.调用BeanPostProcessor的postProcessBeforeInitialization方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("5.调用BeanPostProcessor的postProcessBeforeInitialization方法");
return bean;
}
//8.调用BeanPostProcessor的postProcessAfterInitialization方法
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("8.调用BeanPostProcessor的postProcessAfterInitialization方法");
return bean;
}
}
3.配置bean.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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="book1" destroy-method="myDestroy" init-method="myInit" class="com.atguigu.configuration.BookBean">
<property name="name" value="老人与海"></property>
<property name="author" value="哈利波特"></property>
<property name="id" value="101"></property>
</bean>
<!--配置自定义的后置处理器 -->
<bean id="postProcessor" class="com.atguigu.configuration.MyBeanPostProcessor"></bean>
</beans>
4.测试
public class TestBookBean {
@Test
public void test(){
System.out.println("0.容器开始初始化");
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
System.out.println("xml加载完毕");
BookBean bookBean = context.getBean("book1",BookBean.class);
System.out.println(bookBean.toString());
System.out.println("11.关闭容器");
((ClassPathXmlApplicationContext)context).close();
}
}
5.控制台打印
0.容器开始初始化
BookBean构造方法被调用
1.setNames被调用
1.setAuthor被调用
1.setId被调用
2.调用BeanNameAware的setBeanName方法
3.调用BeanFactoryAware的setBeanFactory方法
4.调用ApplicationContextAware的setApplicationContext方法
5.调用BeanPostProcessor的postProcessBeforeInitialization方法
6.调用InitizingBean的afterPropertiesSet方法
7.调用定制的初始化方法myInit
8.调用BeanPostProcessor的postProcessAfterInitialization方法
xml加载完毕,Bean准备就绪
BookBean{id='101', name='老人与海', author='哈利波特'}
11.关闭容器
9.调用DispostbleBean的destroy方法
9.调用定制的销毁方法
Instance实例例化-》设置属性值-》调⽤用BeanNameAware的setBeanName⽅方法-》调⽤用BeanPostProsessor的预初始化⽅方
法-》调⽤用InitializationBean的afterPropertiesSet()的⽅方法-》调⽤用定制的初始化⽅方法callCustom的init-method-》调⽤用
BeanPostProsessor的后初始化⽅方法-》Bean可以使⽤用了了 -》 容器器关闭-》 调⽤用DisposableBean的destroy⽅方法-》调⽤用定
制的销毁⽅方法CallCustom的destroy-method。
1、Spring对Bean进⾏行行实例例化(相当于程序中的new Xx())
2、Spring将值和Bean的引⽤用注⼊入进Bean对应的属性中
3、如果Bean实现了了BeanNameAware接⼝口,Spring将Bean的ID传递给setBeanName()⽅方法(实现BeanNameAware清主
要是为了了通过Bean的引⽤用来获得Bean的ID,⼀一般业务中是很少有⽤用到Bean的ID的)
4、如果Bean实现了了BeanFactoryAware接⼝口,Spring将调⽤用setBeanDactory(BeanFactory bf)⽅方法并把BeanFactory容器器
实例例作为参数传⼊入。(实现BeanFactoryAware 主要⽬目的是为了了获取Spring容器器,如Bean通过Spring容器器发布事件等)
5、如果Bean实现了了ApplicationContextAwaer接⼝口,Spring容器器将调⽤用setApplicationContext(ApplicationContext ctx)
⽅方法,把y应⽤用上下⽂文作为参数传⼊入.(作⽤用与BeanFactory类似都是为了了获取Spring容器器,不不同的是Spring容器器在调⽤用
setApplicationContext⽅方法时会把它⾃自⼰己作为setApplicationContext 的参数传⼊入,⽽而Spring容器器在调⽤用setBeanDactory
前需要程序员⾃自⼰己指定(注⼊入)setBeanDactory⾥里里的参数BeanFactory )
7、如果Bean实现了了BeanPostProcess接⼝口,Spring将调⽤用它们的postProcessBeforeInitialization(预初始化)⽅方法(作
⽤用是在Bean实例例创建成功后对进⾏行行增强处理理,如对Bean进⾏行行修改,增加某个功能)7.如果Bean实现了了InitializingBean接
⼝口,Spring将调⽤用它们的afterPropertiesSet⽅方法,作⽤用与在配置⽂文件中对Bean使⽤用init-method声明初始化的作⽤用⼀一样,
都是在Bean的全部属性设置成功后执⾏行行的初始化⽅方法。
8、如果Bean实现了了BeanPostProcess接⼝口,Spring将调⽤用它们的postProcessAfterInitialization(后初始化)⽅方法(作
⽤用与7的⼀一样,只不不过7是在Bean初始化前执⾏行行的,⽽而这个是在Bean初始化后执⾏行行的,时机不不同 )
9、经过以上的⼯工作后,Bean将⼀一直驻留留在应⽤用上下⽂文中给应⽤用使⽤用,直到应⽤用上下⽂文被销毁
10、如果Bean实现了了DispostbleBean接⼝口,Spring将调⽤用它的destory⽅方法,作⽤用与在配置⽂文件中对Bean使⽤用destory-
method属性的作⽤用⼀一样,都是在Bean实例例销毁前执⾏行行的⽅方法。
1.1 实例化 也就是我们通常说的new
- setter 方法
- 构造函数
- 静态工厂
- 实例工厂