springAOP和bean生命周期

文章目录
  1. 1. 从注解开始说
  2. 2. 从SpringBoot.run()说
  3. 3. postProcessBeanFactory()
  4. 4. invokeBeanFactoryPostProcessors()
  5. 5. onRefresh();

Springboot是Spring的脚手架,提供的自动配置功能初始化spring的ioc容器,

BeanDefinition:可以理解为定义bean

bean的生命周期,大部分初始化和赋值在AbstractAutowireCapableBeanFactory.doCreateBean 下来定义的:

- 创建bean
- 赋值和变量
- 初始化bean 包括 BeanPostProcessor,initMethod等
- AOP相关的内容
- 被销毁

/assets/images/bean/instantation.jpg

SpringApplicationContext:Spring的容器负责放置初始化好的bean

SpringFactoriesLoader 加载 spring.factories

1. 生成一个SpringApplication的对象

  • 1. webApplicationType = 推测web应用类型(NONE、REACTIVE、SERVLET)
  • 2. 从spring.factories中获取BootstrapRegistryInitializer对象
  • 3. initializers = 从spring.factories中获取ApplicationContextInitializer对象
  • 4. listeners = 从spring.factories中获取ApplicationListener对象

2. SpringApplication的对象.run()

  • 1. 获取SpringApplicationRunListener—->EventPublishingRunListener
  • \2. SpringApplicationRunListener.starting()
  • 3.创建一个Spring容器
  • 4. ApplicationContextInitializer—>初始化Spring容器
  • \5. SpringApplicationRunListener.contextPrepared()
  • 6. 把传给run方法的配置类注册成为一个Bean
  • \7. SpringApplicationRunListener.contextLoaded()
  • 8.会解析配置类、扫描、启动Tomcat/Jetty/Undertow
  • (AutoConfigurationImportSelector,DeferredImportSelector)
  • \9. SpringApplicationRunListener.started() I
  • 10.
  • \10. SpringApplicationRunListener.ready()

从注解开始说

@enableSpringAutoConfig ->Configeration ->inportSelector-> AutoConfigurationImportSelector

@SpringBootConfig- mapperScan

@ComponentScan

autoConfigerationSelector.class 会解析 autoconfig包下面的bean.factory

从SpringBoot.run()说

image-20230104122503870

SpringApplication.run()入口

AbstractApplicationContext.refresh()创建了ApplicationContext容器后刷新

DefaultListableBeanFactory,deGetBean() ApplicationContext集成了 ListableBeanFactory

DefaultSingletonBeanRgistry.getSingleton() 获取单例的bean实例

AbstractAutowireCapableBeanFactory.createBean();创建对应的bean对应上面的Bean的生命周期

newInstance() 初始化一个bean实例

在refresh()方法下对应的方法注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1:准备刷新上下文环境
prepareRefresh();

//2:获取初始化Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//3:对bean工厂进行填充属性
prepareBeanFactory(beanFactory);

try {
//4:Spring开放接口 留给子类去实现该接口
postProcessBeanFactory(beanFactory);

//5:调用我们的bean工厂的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);

//6:注册我们bean后置处理器
registerBeanPostProcessors(beanFactory);

//7:初始化国际化资源处理器
initMessageSource();

//8:初始化事件多播器
initApplicationEventMulticaster();

//9:这个方法同样也是留个子类实现,其中springboot也是从这个方法进行tomcat的启动
onRefresh();

//10:把我们的事件监听器注册到多播器上
registerListeners();

//11:实例化所有的非懒加载的单实例bean
finishBeanFactoryInitialization(beanFactory);

//12:最后刷新容器 发布刷新事件(Spring cloud eureka也是从这里启动的)
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

图片

postProcessBeanFactory()

invokeBeanFactoryPostProcessors()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

processConfigBeanDefinitions的调用逻辑
读取所有的自动配置类(带有@Configuration注解的类)
相当于加载beanDefination
invokeBeanFactoryPostProcessors实现这两个接口可以定制
- BeanDefinitionRegistry对象
- ConfigurableListableBeanFactory对象。

AbstractAutowireCapableBeanFactory.doCreateBean() 下的方法熟悉
- populateBean()
- initializeBean()
- applyBeanPostProcessorsBeforeInitialization()
- processor.postProcessBeforeInitialization(result, beanName)
- invokeAwareInterfaces

image-20230106123943743

onRefresh();

1
AbstractApplicationContext.onRefresh 是空但是AnnotationConfigServletWebServerApplicationContext是实际实现的类,下面有留言

​ /**

Create a new {@link AnnotationConfigServletWebServerApplicationContext} that needs

  • to be populated through {@link #register} calls and then manually
  • {@linkplain #refresh refreshed}.
    */
    AnnotationConfigServletWebServerApplicationContext 继承了ServletWebServerApplicationContext 实现实现onRefresh的类是

image-20230106124800528

实际会启动tomcat服务的

image-20230106125919039

启动

image-20230106131402394

image-20230106131700726

在探究AOP原理之前,让我们先来了解AOP的术语:

Aspect(切面):要实现的散布应用中多处的功能,例如日志记录;

Joinpoint(连接点):应用执行中可以插入切面的点,这个点可以是方法调用、异常抛出甚至是字段值修改,由于Spring AOP构建在动态代理的基础上,所以连接点只支持方法层面;

Pointcut(切点):定义了切面应该插入到哪些连接点,我们并不希望切面插入到所有的连接点,切点能让我们决定切面应该插入到哪些连接点;

Weaving(织入):把切面插入到目标对象上并生成新的代理对象的过程。我们可以在目标对象的编译期(需要特殊的编译器)、类加载期(需要特殊的类加载器)或运行期织入,由于Spring AOP构建在动态代理的基础上,所以只支持在运行期织入;

Introduction(引入):为目标对象添加新方法或新属性的过程,引入使得在不改变目标对象的情况下,让目标对象具有新的行为和状态;

Advice(通知):定义了切面何时被触发,Spring目前有5种类型的通知,分别是:BeforeAdvice(前置通知)、AfterAdvice(后置通知)、AfterReturningAdvice(返回通知)、ThrowsAdvice(异常通知)和AroundAdvice(环绕通知)。

one-ok

参考链接:聊透Spring bean的生命周期 - 掘金,Spring Boot详细生命周期介绍 - 知乎,Spring详细生命周期介绍 - 知乎,@Pointcut()的execution、@annotation等参数说明Normal Developer的博客-CSDN博客@annotation ,Spring IOC和Bean生命周期源码分析 ,Spring中Bean注入源码分析 - 掘金