spring Bean初始化
morris131 人气:0AbstractAutowireCapableBeanFactory#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。
注意这三种初始化方法都不能带有参数。
加载全部内容