yehao
发布于 2023-12-08 / 40 阅读
0
0

spring 相关

spring bean的生命周期

public class TestBeanProcessor implements BeanPostProcessor,InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        // bean实例化之前
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        // bean实例化之后
        return true;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // bean初始化之前
        return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // bean初始化之后
        return null;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        // bean销毁之前
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}

自定义 InstantiationAwareBeanPostProcessor

注册beanDefition到beanFactory, 在执行getBean时,进行bean的实例化(如果有自定义InstantiationAwareBeanPostProcessor,调用自身实现的实例化,返回为空则继续走默认实例化)

属性注入(aware)

初始化(@PostPointCut 等bean初始化后的操作)

业务操作

销毁

sping aop的实现方式

入口

AnnotationConfigApplicationContext  --> 构造reader注册 && scaner扫描

引入 spring-boot-starter-aop 后, 会自动启动EnableAspectJAutoProxy

AopConfiguration 会自动启动

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {

   @Configuration(proxyBeanMethods = false)
   @EnableAspectJAutoProxy(proxyTargetClass = false)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
   static class JdkDynamicAutoProxyConfiguration {

   }

   @Configuration(proxyBeanMethods = false)
   @EnableAspectJAutoProxy(proxyTargetClass = true)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
         matchIfMissing = true)
   static class CglibAutoProxyConfiguration {

   }

}

启动后会自动引入 AspectJAutoProxyRegistrar ( ImportBeanDefinitionRegistrar)

调用 registerBeanDefinitions方法,会注册一个 AnnotationAwareAspectJAutoProxyCreator的beanDifnition

AnnotationAwareAspectJAutoProxyCreator 就是 一个 beanFactoryPostProcessor,继承于AbstractAutoProxyCreator

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			// 此处为核心实现, 返回了一个代理对象。
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

总结:

引入spring-aop-starter之后,

会引入 AspectJAutoProxyRegistrar 自动代理注册器

自动代理注册器注册一个beanPostProcessor AnnotationAwareAspectJAutoProxyCreator

在bean创建的生命周期的扩展中,直接返回一个代理对象。

ean未添加aop时,会创建代理对象吗?

springboot是如何实现自动装配的?

注解入口,

@EnableAutoConfiguration -->

importSelector -->

spring.factories (spi机制) -->

读取对应的XXXAutoConfiguration

(@ConditionOnXXX进行智能装配,ConditionBefore,ConditionAfter定义顺序依赖)

springboot启动的事件机制?

  • SpringbootApplication构造方法

1> 配置ResourceLoader、primarySources(主入口,扫描包相关)

2>  通过classpath推断webAppType

3> 配置ApplicationContextInitialler (spring.factories)

4> 配置应用监听器 ApplicationListener (spring.factories)

5> 通过异常堆栈 推断出 主入口类的classname

  • run方法

6> 配置监听器 SpringbootApplicationRunListener(从spring.factories中获取所有配置的listener,此listener相当于广播ApplicationEvent),runlistener相当于一个事件触发器,将不同时机封装成不同event广播出去,被其他listener接收处理

7> 通过spring.factories 获取到异常报告器(ExceptionReport)

8> prepareContext refreshContext afterRefreshContext

9> callRunner (启动后根据入口参数回调) ApplicationRunner

10> 其他事件(starting开始启动,environmentPrepared环境准备就绪,contextPrepared上下文准备就绪,contextloaded上下文加载完成,started启动完成,running运行中,failed启动失败)(4>步的ApplicationListener监听各种事件,处理不同操作)

spring ioc bean注册创建流程

1.加载配置(Xml)或者注册注解(AnnotationConfigApplicationContext) --> BeanDefinition

2.调用getBean方法时,创建bean:bean的声明周期可用户自定义实现InstantiationAwareBeanPostProcessor自定义bean实例,否则走默认创建 --> 开启aop ? 创建代理 : 默认创建bean, 实例化、参数设置,初始化(BeanPostProcessor),销毁(DestoryAwarePostProcessor)。


评论