Spring执行流程
说明:这里只是说的大概流程,不是严格按照源码上一步一步说的。
简单来说,分为下边四个步骤:
- 启动Spring容器
- 实例化Bean(分配内存空间)
- 将Bean注册到Spring当中(存操作)
- 将Bean装配到需要的类中(取操作)
实例化和初始化的区别
实例化:在堆上开辟内存,将非静态的变量和方法放到里边。
初始化:静态成员(变量、方法、代码块)会被执行,并在一块存储空间存放静态数据。
- 初始化只在类加载时执行一次,可多次实例化
- 初始化做的是执行+开内存(静态),实例是开内存(非静态)
实例化是更加靠前的。
Bean的生命周期
Bean的生命周期就是Bean对象从出生到死亡的过程。Bean的生命周期分为五大部分:
1.实例化
2.设置属性
3.Bean初始化
4.使用Bean
5.销毁Bean
1.Bean实例化
实例化本质上就是在开辟内存空间。
实例化不等于初始化,实例化是更加靠前的。
2.设置属性
设置属性本质上是在加载依赖项。
在此过程中,会完成Bean的注入和装配。
如果当前类使用的Bean还没有,任务停止,开始去做那个Bean的实例和初始化
3.初始化Bean
- 执行各种通知方法
- 执行初始化前置方法【两种实现方式:xml方式、注解方式】
- 执行初始化方法
- 初始化后置方法
其中前置方法和后置方法用的是比较少的,但是初始化方法用的是比较多的。
4.使用Bean
5.销毁Bean
步骤2和3为什么不能颠倒
因为可能在调用方法的时候可能用到依赖的对象,必须要先进行属性注入。
代码演示:
使用xml方式初始化:
【bean属性用的不是特别多】这里只做了解
Component类:
说明:这里多调用了几个通知类
package com.java.demo.component;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class BeanComponent implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,BeanPostProcessor {
//通知方法
@Override
public void setBeanName(String s) {
System.out.println("执行了通知BeanName->"+s);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("执行了通知BeansException->"+beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("执行了通知ApplicationContext applicationContext->"+applicationContext);
}
//xml方式的初始化方法
public void myInit(){
System.out.println("XML方式初始化");
}
//注解的初始化方法
@PostConstruct
public void doPostConstruct(){
System.out.println("注解的初始化方法");
}
//销毁的方法
@PreDestroy
public void doPreDestory(){
System.out.println("do PreDestory()");
}
public void sayHi(){
System.out.println("do BeanComponent sayHi()");
}
}
启动类:
说明:其中这里使用ClassPathXmlApplicationContext,是因为ApplicationContext没有destrory方法,没法看效果。
public class App {
public static void main(String[] args) {
//Application没有销毁方法
ClassPathXmlApplicationContext context1=new ClassPathXmlApplicationContext("spring-config.xml");
BeanComponent beanComponent=context1.getBean("beanComponent",BeanComponent.class);
beanComponent.sayHi();
//销毁容器(跟着,对象也销毁了)
context1.destroy();
}
}
打印效果:
因为现在使用注解比较多,相应的注解的优先级也更高。
初始各方法 补充
通知方法:例如BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接口方法
PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。
前置和后置方法都是接口
Bean初始化过程
- 实现各种Aware通知方法,如BeanNameAware等接口的方法
- 执行BeanPosProcessor初始化前置方法
- 执行@PostConstruct初始化方法,依赖注入操作之后被执行
- 执行自己指定的init方法(如果在配置文件中指定了的话)
83639755062)]
Bean初始化过程
- 实现各种Aware通知方法,如BeanNameAware等接口的方法
- 执行BeanPosProcessor初始化前置方法
- 执行@PostConstruct初始化方法,依赖注入操作之后被执行
- 执行自己指定的init方法(如果在配置文件中指定了的话)
- 执行BeanPostProcessor初始化后置方法