spring Bean的初始化过程解析
作者:morris131
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、@Value
- CommonAnnotationBeanPostProcessor:负责@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<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> 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 beanDefinition, 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<InjectedElement> checkedElements = this.checkedElements; Collection<InjectedElement> 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<Object>) () -> { 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<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主要负责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<Object>) () -> { ((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); }
运行结果如下:
PostConstruct
afterPropertiesSet
init
运行结果与源码分析的一致,先执行PostConstruct,再执行afterPropertiesSet,最后initMethod。
注意这三种初始化方法都不能带有参数。
到此这篇关于spring Bean的初始化过程的文章就介绍到这了,更多相关spring Bean初始化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!