赞
踩
点击了解 Spring bean生命周期之(1)BeanDefinition
在Bean创建阶段主要包括:Spring Bean
实例化前阶段、Spring Bean
实例化阶段、Spring Bean
实例化后阶段等阶段。
InstantiationAwareBeanPostProcessor
:
Spring Bean
实例化前阶段:第一次调用后置处理器 postProcessBeforeInstantiation
方法,默认实现是判断是否需要代理放入map中Spring Bean
实例化后置阶段:第五次调用后置处理器 postProcessAfterInstantiation
方法 ,属性赋值(Populate)判断是否需要属性填充populateBean
属性赋值 :第六次调用后置处理器:postProcessPropertyValues
为bean
填充属性包括依赖注入的属性SmartInstantiationAwareBeanPostProcessor
后置处理器:determineCandidateConstructors
获取最优构造方法实例化对象SmartInstantiationAwareBeanPostProcessor
后置处理器getEarlyBeanReference
解决循环依赖的问题相关入口:
根据类型获取Bean
org.springframework.context.support.AbstractApplicationContext.getBean(Class<T>)
根据名字获取Bean
org.springframework.context.support.AbstractApplicationContext.getBean(String)
实际获取Bean
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
根据给出的Bean获取真实Bean(可能是factoryBean)
org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance
创建Bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean
实际创建Bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
下面是 的相关源码
AbstractApplicationContext.finishBeanFactoryInitialization()实例化bean入口方法
//创建Bean实例对象 @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 校验和准备Bean中的方法覆盖 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象 //TODO 第一次调用bean的后置处理器 主要判断bean需要被代理 bean一般都为空 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //创建Bean的入口 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException ex) { // A previously detected exception with proper bean creation context already... throw ex; } catch (ImplicitlyAppearedSingletonException ex) { // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry... throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
第一次调用后置处理器
非主流生命周期 – Bean 实例化前阶段:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- <context:annotation-config/>--> <!-- <context:component-scan base-package="org.acme" />--> <!-- Root BeanDefinition 不需要合并,不存在 parent --> <!-- 普通 beanDefinition GenericBeanDefinition --> <!-- 经过合并后 GenericBeanDefinition 变成 RootBeanDefinition --> <bean id="user" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User"> <property name="id" value="1"/> <property name="name" value="小马哥"/> <property name="city" value="HANGZHOU"/> <property name="workCities" value="BEIJING,HANGZHOU"/> <property name="lifeCities"> <list> <value>BEIJING</value> <value>SHANGHAI</value> </list> </property> <property name="configFileLocation" value="classpath:/META-INF/user-config.properties"/> </bean> <!-- 普通 beanDefinition GenericBeanDefinition --> <!-- 合并后 GenericBeanDefinition 变成 RootBeanDefinition,并且覆盖 parent 相关配置--> <!-- primary = true , 增加了一个 address 属性 --> <bean id="superUser" class="org.geekbang.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user" primary="true"> <property name="address" value="杭州"/> </bean> </beans>
spring 内置的实现 (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)
代码位置:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(beanName, mbdToUse)
@Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. //TODO mbd.isSynthetic() 表示是否合成类 // hasInstantiationAwareBeanPostProcessors() 判断系统是否有 InstantiationAwareBeanPostProcessors if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //这个一般都是为空 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
主要实现类就一个AbstractAutoProxyCreator#postProcessBeforeInstantiation
主要作用是判断 bean
是否需要被代理 ,需要被代理的类 就放入map中
@Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //advisedBeans 不需要被代理的对象 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; }
实例化阶段主要是 根据后置处理器 推断出 实例化bean的最优构造方法,实例化对象。
第二次调用bean的后置处理器:推断实例化构造方法—》SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors
路径:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance(beanName, mbd, args)
接口:
SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)
实现类:
AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
这个后置处理器 需要实现 SmartInstantiationAwareBeanPostProcessor接口
实例化方式:
instantiateBean(beanName, mbd)
autowireConstructor(beanName, mbd, ctors, args)
接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
其中推断构造器的规则
这个分两种类型
当推断出来使用默认无参构造
//使用默认的无参构造方法实例化Bean对象 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; //获取系统的安全管理接口,JDK标准的安全管理API if (System.getSecurityManager() != null) { //这里是一个匿名内置类,根据实例化策略创建实例对象 beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { //将实例化的对象封装起来 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
使用条件:推断处理的 构造器方法不为null或者开启自动装配或者 使用指定入参的构造方法
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用容器的自动装配特性,调用匹配的构造方法实例化
//使用推断出来的构造方法找到一个可以用的 实例化bean
return autowireConstructor(beanName, mbd, ctors, args);
}
具有实现:ConstructorResolver#autowireConstructor 这里会再次推断构造方法实例化对象。
实例化后会第三和第四调用后置处理器
这里主要解决 处理合并BeanDefinition的问题
入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
接口:这个后置处理器 需要实现 MergedBeanDefinitionPostProcessor 接口中的postProcessMergedBeanDefinition方法
合并相关介绍:
为什么会提前合并
通过类型找到名字—返回一个BeanFactoryPostProcessor
的集合–完成了合并
不能用原始的BeanDefinition 去比较 必须合并
代码流程 —AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);–>>PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());–>DefaultListableBeanFactory.getBeanNamesForType(@Nullable Class<?> type) -->RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//通过类型找到名字---返回一个BeanFactoryPostProcessor的集合--完成了合并
//返回一个BeanDefinition 后置工厂的名字的集合--通过名字实例化BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
但是在实例化bean的时候会重新在去 合并bd 会把缓存中的合并后的BeanDefinition
删除在重新合并
AbstractAutowireCapableBeanFactory applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用后置处理的源码
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);
}
}
}
findAutowiredMetadata
----找出所有需要完成注入的“点”-----@Autowired
@Value
注解方法或者属性—为什么不需要构造方法
checkConfigMembers
----injectedElements 做了一个复制
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
调用父类的方法,查找所有的生命周期回调方法—初始化和销毁
findResourceMetadata
----找出所有需要完成注入的“点”-----@Resource
注解
checkConfigMembers
----injectedElements 做了一个复制
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
两者使用的bean的后置处理器不一样的。
这个阶段主要判断当前实例化的bean
是否需要属性注入
路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(beanName, mbd, instanceWrapper)
//todo 第五次---属性是否注入InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
接口:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
所有spring内置的实现类都为true
我们当创建use bean的时候放回 false。这样这个bean就不会填充任何属性了。
/** * Bean 实例化生命周期示例 * */ public class BeanInstantiationDemo { public static void main(String[] args) { DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorDome()); XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); String location = "META-INF/dependency-lookup-context.xml"; Resource resource = new ClassPathResource(location); // 指定字符编码 UTF-8 EncodedResource encodedResource = new EncodedResource(resource, "UTF-8"); beanDefinitionReader.loadBeanDefinitions(encodedResource); // 通过 Bean Id 和类型进行依赖查找 User user = beanFactory.getBean("user", User.class); System.out.println(user); User superUser = beanFactory.getBean("superUser", User.class); System.out.println(superUser); } /** * 实现 后置处理器 */ static class MyInstantiationAwareBeanPostProcessorDome implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){ //把配置完成的 superUser bean覆盖 return new SuperUser(); } return null;//这里表示什么都不变化 } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){ //如果是 user 对象不允许属性的赋值 return false; } return true;//这里表示什么都不变化 } } }
参考链接:https://blog.csdn.net/qq_36697880/article/details/113836822
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。