spring?Bean的初始化過(guò)程解析

AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
使用BeanPostProcessor收集帶有注解的方法和屬性,方便下面初始化時(shí)調(diào)用。
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主要有以下兩個(gè):
- AutowiredAnnotationBeanPostProcessor:負(fù)責(zé)@Autowired、@Value
- CommonAnnotationBeanPostProcessor:負(fù)責(zé)@Resource、@PostConstruct、@PreDestroy
AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
AutowiredAnnotationBeanPostProcessor負(fù)責(zé)@Autowired、@Value注解的方法和屬性的收集。
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// autowiredAnnotationTypes是在構(gòu)造方法中被初始化的
// autowiredAnnotationTypes @Autowired @Value
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 查找?guī)в蠤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));
}
});
// 查找?guī)в蠤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負(fù)責(zé)@Resource、@PostConstruct、@PreDestroy注解的方法和屬性的收集,收集過(guò)程與AutowiredAnnotationBeanPostProcessor的收集過(guò)程類似。
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 構(gòu)造方法會(huì)注入@PostConstruct、@PreDestroy
// 父類會(huì)查找?guī)в蠤PostConstruct、@PreDestroy注解的方法
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
// 查找?guī)в蠤Resource注解的屬性和方法
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
AbstractAutowireCapableBeanFactory#populateBean
調(diào)用各個(gè)BeanPostProcessor.postProcessProperties對(duì)屬性進(jìn)行設(shè)置。
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;
// 調(diào)用各個(gè)BeanPostProcessor.postProcessProperties對(duì)屬性進(jìn)行設(shè)置
/**
* 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
對(duì)帶有@Resource注解的屬性進(jìn)行設(shè)置,對(duì)帶有@Resource注解的方法進(jìn)行調(diào)用。
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 上面的方法postProcessMergedBeanDefinition向緩存中設(shè)置了@PostConstruct、@PreDestroy注解的方法,@Resource注解的屬性和方法
// 這里會(huì)從緩存中取出對(duì)這些屬性進(jìn)行設(shè)置,方法進(jìn)行調(diào)用
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方法也是如此,對(duì)帶有@Autowired注解的屬性進(jìn)行設(shè)置,對(duì)帶有@Autowired注解的方法進(jìn)行調(diào)用。
InjectionMetadata#inject
org.springframework.beans.factory.annotation.InjectionMetadata#inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
/**
* CommonAnnotationBeanPostProcessor注入的是InjectionMetadata.InjectedElement對(duì)象
* @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的調(diào)用主要是反射進(jìn)行屬性的設(shè)置和方法的調(diào)用,如果屬性是引用類型,將會(huì)觸發(fā)beanFactory.getBean()方法從Spring容器中獲取對(duì)象。
AbstractAutowireCapableBeanFactory#initializeBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
上面的populateBean()完成了對(duì)象的初始化,下面將會(huì)調(diào)用對(duì)象的初始化方法完成最后的初始化過(guò)程。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 調(diào)用aware方法
// BeanNameAware/BeanClassLoaderAware/BeanFactoryAware對(duì)應(yīng)的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()
// 調(diào)用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接口的初始化方法調(diào)用,還有部分aware接口將通過(guò)下面的BeanPostProcessor完成調(diào)用。
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調(diào)用EnvironmentAware/EmbeddedValueResolverAware/ResourceLoaderAware/
* ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware
*
* ImportAwareBeanPostProcessor調(diào)用ImportAware(Bean不僅需要實(shí)現(xiàn)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負(fù)責(zé)EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware接口的調(diào)用。
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<Object>) () -> {
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主要負(fù)責(zé)ImportAware接口的調(diào)用。
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必須通過(guò)@Import注解注入進(jìn)來(lái),importingClass才會(huì)有值
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緩存數(shù)據(jù)從何來(lái)?
// 前面在調(diào)用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@Resource注解時(shí),同時(shí)會(huì)調(diào)用
// 父類InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@PostConstruct注解
// 負(fù)責(zé)@PostConstruct方法的調(diào)用
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緩存數(shù)據(jù)從何來(lái)?前面在調(diào)用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@Resource注解時(shí),同時(shí)會(huì)調(diào)用
父類InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition收集@PostConstruct注解。
而PostConstruct注解是在CommonAnnotationBeanPostProcessor的構(gòu)造方法中指定的。
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<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 調(diào)用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)) {
// 調(diào)用init-method
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
@PostConstruct、afterPropertiesSet、init-method
@PostConstruct、InitializingBean.afterPropertiesSet、init-method這三者要實(shí)現(xiàn)的功能都是一致的,都是在bean實(shí)例化并初始化完成之后進(jìn)行調(diào)用。
具體使用如下:
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);
}運(yùn)行結(jié)果如下:
PostConstruct
afterPropertiesSet
init
運(yùn)行結(jié)果與源碼分析的一致,先執(zhí)行PostConstruct,再執(zhí)行afterPropertiesSet,最后initMethod。
注意這三種初始化方法都不能帶有參數(shù)。
到此這篇關(guān)于spring Bean的初始化過(guò)程的文章就介紹到這了,更多相關(guān)spring Bean初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)對(duì)服務(wù)器的自動(dòng)巡檢郵件通知
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)對(duì)服務(wù)器的自動(dòng)巡檢郵件通知,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段
這篇文章主要為大家詳細(xì)介紹了java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
spring配置文件中util:properties和context:property-placeholder用法
這篇文章主要介紹了spring配置文件中util:properties和context:property-placeholder用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板實(shí)現(xiàn)demo
這篇文章主要為大家介紹了flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
springboot?jpa?實(shí)現(xiàn)返回結(jié)果自定義查詢
這篇文章主要介紹了springboot?jpa?實(shí)現(xiàn)返回結(jié)果自定義查詢方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Gradle構(gòu)建多模塊項(xiàng)目的方法步驟
這篇文章主要介紹了Gradle構(gòu)建多模塊項(xiàng)目的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
SpringBoot整個(gè)啟動(dòng)過(guò)程的分析
今天小編就為大家分享一篇關(guān)于SpringBoot整個(gè)啟動(dòng)過(guò)程的分析,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03

