spring Bean的初始化过程解析

网友投稿 331 2022-08-22


spring Bean的初始化过程解析

AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

使用BeanPostProcessor收集带有注解的方法和属性,方便下面初始化时调用。org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class> beanType, String beanName) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof MergedBeanDefinitionPostProcessor) {

MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;

bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);

}

}

}

这里的BeanPostProcessor主要有以下两个:

AutowiredAnnotationBeanPostProcessor:负责@Autowired、@ValueCommonAnnotationBeanPostProcessor:负责@Resource、@PostConstruct、@PreDestroy

AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

AutowiredAnnotationBeanPostProcessor负责@Autowired、@Value注解的方法和属性的收集。

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {

// autowiredAnnotationTypes是在构造方法中被初始化的

// autowiredAnnotationTypes @Autowired @Value

if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {

return InjectionMetadata.EMPTY;

}

List elements = new ArrayList<>();

Class> targetClass = clazz;

do {

final List currElements = new ArrayList<>();

// 查找带有@Autowired注解的属性

ReflectionUtils.doWithLocalFields(targetClass, field -> {

MergedAnnotation> ann = findAutowiredAnnotation(field);

if (ann != null) {

if (Modifier.isStatic(field.getModifiers())) {

if (logger.isInfoEnabled()) {

logger.info("Autowired annotation is not supported on static fields: " + field);

}

return;

}

boolean required = determineRequiredStatus(ann);

currElements.add(new AutowiredFieldElement(field, required));

}

});

// 查找带有@Autowired注解的方法

ReflectionUtils.doWithLocalMethods(targetClass, method -> {

Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);

if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {

return;

}

MergedAnnotation> ann = findAutowiredAnnotation(bridgedMethod);

if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {

if (Modifier.isStatic(method.getModifiers())) {

if (logger.isInfoEnabled()) {

logger.info("Autowired annotation is not supported on static methods: " + method);

}

return;

}

if (method.getParameterCount() == 0) {

if (logger.isInfoEnabled()) {

logger.info("Autowired annotation should only be used on methods with parameters: " +

method);

}

}

boolean required = determineRequiredStatus(ann);

PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);

currElements.add(new AutowiredMethodElement(method, required, pd));

}

});

elements.addAll(0, currElements);

targetClass = targetClass.getSuperclass();

}

while (targetClass != null && targetClass != Object.class);

return InjectionMetadata.forElements(elements, clazz);

}

CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

CommonAnnotationBeanPostProcessor负责@Resource、@PostConstruct、@PreDestroy注解的方法和属性的收集,收集过程与AutowiredAnnotationBeanPostProcessor的收集过程类似。

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

public void postProcessMergedBeanDefinition(RootBeanDefinition behttp://anDefinition, Class> beanType, String beanName) {

// 构造方法会注入@PostConstruct、@PreDestroy

// 父类会查找带有@PostConstruct、@PreDestroy注解的方法

super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);

// 查找带有@Resource注解的属性和方法

InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);

metadata.checkConfigMembers(beanDefinition);

}

AbstractAutowireCapableBeanFactory#populateBean

调用各个BeanPostProcessor.postProcessProperties对属性进行设置。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

... ...

if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

// 调用各个BeanPostProcessor.postProcessProperties对属性进行设置

/**

* AutowiredAnnotationBeanPostProcessor处理@Autowired

* CommonAnnotationBeanPostProcessor处理@Resource

*

* @see AutowiredAnnotationBeanPostProcessor#postProcessProperties(org.springframework.beans.PropertyValues, java.lang.Object, java.lang.String)

* @see org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties(org.springframework.beans.PropertyValues, java.lang.Object, java.lang.String)

*/

PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

... ...

}

CommonAnnotationBeanPostProcessor#postProcessProperties

对带有@Resource注解的属性进行设置,对带有@Resource注解的方法进行调用。

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {

// 上面的方法postProcessMergedBeanDefinition向缓存中设置了@PostConstruct、@PreDestroy注解的方法,@Resource注解的属性和方法

// 这里会从缓存中取出对这些属性进行设置,方法进行调用

InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);

try {

/**

* @see org.springframework.beans.factory.annotation.InjectionMetadata#inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues)

*/

metadata.inject(bean, beanName, pvs);

}

catch (Throwable ex) {

throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);

}

return pvs;

}

AutowiredAnnotationBeanPostProcessor#postProcessProperties方法也是如此,对带有@Autowired注解的属性进行设置,对带有@Autowired注解的方法进行调用。

InjectionMetadata#inject

org.springframework.beans.factory.annotation.InjectionMetadata#inject

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {

Collection checkedElements = this.checkedElements;

Collection elementsToIterate =

(checkedElements != null ? checkedElements : this.injectedElements);

if (!elementsToIterate.isEmpty()) {

for (InjectedElement element : elementsToIterate) {

/**

* CommonAnnotationBeanPostProcessor注入的是InjectionMetadata.InjectedElement对象

* @see InjectedElement#inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues)

*

* AutowiredAnnotationBeanPostProcessor注入的是AutowiredFieldElement和AutowiredMethodElement

* @see AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues)

* @see AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject(java.lang.Object, java.lang.String, org.springframework.beans.PropertyValues)

*/

element.inject(target, beanName, pvs);

}

}

}

InjectedElement的调用主要是反射进行属性的设置和方法的调用,如果属性是引用类型,将会触发beanFactory.getBean()方法从Spring容器中获取对象。

AbstractAutowireCapableBeanFactory#initializeBean

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

上面的populateBean()完成了对象的初始化,下面将会调用对象的初始化方法完成最后的初始化过程。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

if (System.getSecurityManager() != null) {

AccessController.doPrivileged((PrivilegedAction) () -> {

invokeAwareMethods(beanName, bean);

return null;

}, getAccessControlContext());

}

else {

// 调用aware方法

// BeanNameAware/BeanClassLoaderAware/BeanFactoryAware对应的setXxx方法

invokeAwareMethods(beanName, bean);

}

Object wrappedBean = bean;

if (mbd == null || !mbd.isSynthetic()) {

// 处理EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/

// ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware

// 处理@PostConstruct

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

}

try {

// InitializingBean.afterPropertiesSet()

// 调用init-method

invokeInitMethods(beanName, wrappedBean, mbd);

}

catch (Throwable ex) {

throw new BeanCreationException(

(mbd != null ? mbd.getResourceDescription() : null),

beanName, "Invocation of init method failed", ex);

}

if (mbd == null || !mbd.isSynthetic()) {

// AOP代理入口

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

}

return wrappedBean;

}

AbstractAutowireCapableBeanFactory#invokeAwareMethods

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

这里只完成了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口的初始化方法调用,还有部分aware接口将通过下面的BeanPostProcessor完成调用。

private void invokeAwareMethods(String beanName, Object bean) {

if (bean instanceof Aware) {

if (bean instanceof BeanNameAware) {

((BeanNameAware) bean).setBeanName(beanName);

}

if (bean instanceof BeanClassLoaderAware) {

ClassLoader bcl = getBeanClassLoader();

if (bcl != null) {

((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);

}

}

if (bean instanceof BeanFactoryAware) {

((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);

}

}

}

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)

throws BeansException {

Object result = existingBean;

for (BeanPostProcessor processor : getBeanPostProcessors()) {

/**

* ApplicationContextAwareProcessor调用EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/

* ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware

*

* ImportAwareBeanPostProcessor调用ImportAware(Bean不仅需要实现ImportAware接口,还要有@Import注解)

* InitDestroyAnnotationBeanPostProcessor 处理@PostConstruct

*

* @see org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)

* @see org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)

* @see org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)

*/

Object current = processor.postProcessBeforeInitialization(result, beanName);

if (current == null) {

return result;

}

result = current;

}

return result;

}

ApplicationContextAwareProcessor#postProcessBeforeInitialization

ApplicationContextAwareProcessor负责EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware接口的调用。

org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||

bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||

bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){

return bean;

}

AccessControlContext acc = null;

if (System.getSecurityManager() != null) {

acc = this.applicationContext.getBeanFactory().getAccessControlContext();

}

if (acc != null) {

AccessController.doPrivileged((PrivilegedAction) () -> {

invokeAwareInterfaces(bean);

return null;

}, acc);

}

else {

invokeAwareInterfaces(bean);

}

return bean;

}

private void invokeAwareInterfaces(Object bean) {

if (bean instanceof EnvironmentAware) {

((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());

}

if (bean instanceof EmbeddedValueResolverAware) {

((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);

}

if (bean instanceof ResourceLoaderAware) {

((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);

}

if (bean instanceof ApplicationEventPublisherAware) {

((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);

}

if (bean instanceof MessageSourceAware) {

((MessageSourceAware) bean).setMessageSource(this.applicationContext);

}

if (bean instanceof ApplicationContextAware) {

((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);

}

}

ImportAwareBeanPostProcessor#postProcessBeforeInitialization

ImportAwareBeanPostProcessor主要负责ImportAware接口的调用。

ImportAware的具体使用如下:

ImportAwareBean.java

package com.morris.spring.entity.imports;

import org.springframework.context.annotation.ImportAware;

import org.springframework.core.type.AnnotationMetadata;

public class ImportAwareBean implements ImportAware {

@Override

public void setImportMetadata(AnnotationMetadata importMetadata) {

// 在这里可以拿到注入ImportAwareBean的类ImportConfig上的注解@Transactional

System.out.println(importMetadata.getAnnotationTypes());

}

}

ImportConfig.java

package com.morris.spring.config;

import com.morris.spring.entity.imports.ImportAwareBean;

import org.springframework.context.annotation.Import;

import org.springframework.transaction.annotation.Transactional;

@Transactional

@Import(ImportAwareBean.class)

public class ImportConfig {

}

org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor#postProcessBeforeInitialization

public Object postProcessBeforeInitialization(Object bean, String beanName) {

if (bean instanceof ImportAware) {

ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);

// bean必须通过@Import注解注入进来,importingClass才会有值

AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());

if (importingClass != null) {

((ImportAware) bean).setImportMetadata(importingClass);

}

}

return bean;

}

InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

// LifecycleMetadata缓存数据从何来?

// 前面在调用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@Resource注解时,同时会调用

// 父类InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@PostConstruct注解

// 负责@PostConstruct方法的调用

LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());

try {

metadata.invokeInitMethods(bean, beanName);

}

catch (InvocationTargetException ex) {

throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());

}

catch (Throwable ex) {

throw new BeanCreationException(beanName, "Failed to invoke init method", ex);

}

return bean;

}

LifecycleMetadata缓存数据从何来?前面在调用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@Resource注解时,同时会调用父类InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@PostConstruct注解。

而PostConstruct注解是在CommonAnnotationBeanPostProcessor的构造方法中指定的。

public CommonAnnotationBeanPostProcessor() {

setOrder(Ordered.LOWEST_PRECEDENCE - 3);

setInitAnnotationType(PostConstruct.class);

setDestroyAnnotationType(PreDestroy.class);

ignoreResourceType("javax.xml.ws.WebServiceContext");

}

AbstractAutowireCapableBeanFactory#invokeInitMethods

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)

throws Throwable {

boolean isInitializingBean = (bean instanceof InitializingBean);

if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {

if (logger.isTraceEnabled()) {

logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");

}

if (System.getSecurityManager() != null) {

try {

AccessController.doPrivileged((PrivilegedExceptionAction) () -> {

((InitializingBean) bean).afterPropertiesSet();

return null;

}, getAccessControlContext());

}

catch (PrivilegedActionException pae) {

throw pae.getException();

}

}

else {

// 调用InitializingBean.afterPropertiesSet()

((InitializingBean) bean).afterPropertiesSet();

}

}

if (mbd != null && bean.getClass() != NullBean.class) {

String initMethodName = mbd.getInitMethodName();

if (StringUtils.hasLength(initMethodName) &&

!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&

!mbd.isExternallyManagedInitMethod(initMethodName)) {

// 调用init-method

invokeCustomInitMethod(beanName, bean, mbd);

}

}

}

@PostConstruct、afterPropertiesSet、init-method

@PostConstruct、InitializingBean.afterPropertiesSet、init-method这三者要实现的功能都是一致的,都是在bean实例化并初始化完成之后进行调用。

具体使用如下:

InitBean.java

package com.morris.spring.entity;

import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;

public class InitBean implements InitializingBean {

@PostConstruct

public void postConstruct() {

System.out.println("PostConstruct");

}

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("afterPropertiesSet");

public void init(){

System.out.println("init");

}

InitDemo.java

package com.morris.spring.demo.annotation;

import com.morris.spring.entity.InitBean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class InitDemo {

@Bean(initMethod = "init")

public InitBean initBean() {

return new InitBean();

}

public static void main(String[] args) {

new AnnotationConfigApplicationContext(InitDemo.class);

}

运行结果如下:

PostConstructafterPropertiesSetinit

运行结果与源码分析的一致,先执行PostConstruct,再执行afterPropertiesSet,最后initMethod。

注意这三种初始化方法都不能带有参数。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:mybatis 传入null值的解决方案
下一篇:SpringBoot通过注解注入Bean的几种方式解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~