赞
踩
目录
1、InstantiationAwareBeanPostProcessor :
2、martInstantiationAwareBeanPostProcessor 后置处理器:
3、SmartInstantiationAwareBeanPostProcessor后置处理器
4、InstantiationAwareBeanPostProcessor初始化后置处理器
3.2、spring 内置的实现 (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)
4.2、instantiateBean(beanName, mbd)使用默认无参构造器实例化对象
4.3、使用依赖注入的构造器实例化对象:autowireConstructor(beanName, mbd, ctors, args)
五、处理合并BeanDefinition与解决循环依赖后置处理器
5.1、第三调用后置处理器MergedBeanDefinitionPostProcessor
6.1、第五次调用后置处理器 :属性是否注入InstantiationAwareBeanPostProcessor
经过上一篇的BeanDefinition 生成过程后,已经得到实例化bean的相关的源信息,这一篇重点介绍spring bean的实例化的过程,也就是我们通常的创建对象,不过这样需要推断构造器,使用反射实例化对象。
此阶段主要包括: Spring Bean 实例化前阶段、Spring Bean 实例化阶段、Spring Bean 实例化后阶段等阶段。
第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象
第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题
在实例化阶段主要涉及 1到3 后置处理器 如下图:
相关入口:
- 根据类型获取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
自己实现后置处理器的postProcessBeforeInstantiation 方法替换把配置完成的 superUser bean覆盖。重新生成一个superUser bean。
- <?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>
- 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;//这里表示什么都不变化
- }
- }
- }
执行日志。我们可以看到 SuperUser 只是实例化了 ,什么属性都没有填充
User{id=1, name='小马哥', city=HANGZHOU, workCities=[BEIJING, HANGZHOU], lifeCities=[BEIJING, SHANGHAI], configFileLocation=class path resource [META-INF/user-config.properties], company=null, context=null, contextAsText='null', beanName='user'}
SuperUser{address='null'} User{id=null, name='null', city=null, workCities=null, lifeCities=null, configFileLocation=null, company=null, context=null, contextAsText='null', beanName='null'}
代码位置: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接口
实例化方式:
1、使用默认无参构造器:instantiateBean(beanName, mbd)
实例化策略 - InstantiationStrategy--- instantiationStrategy = new CglibSubclassingInstantiationStrategy()---- SimpleInstantiationStrategy
2、使用依赖注入的构造器:autowireConstructor(beanName, mbd, ctors, args)
createBeanInstance 代码实现
- //创建Bean的实例对象
- protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
- // Make sure bean class is actually resolved at this point.
- //检查确认Bean是可实例化的
- Class<?> beanClass = resolveBeanClass(mbd, beanName);
-
- //使用工厂方法对Bean进行实例化
- if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
- }
- //todo 这个程序员自己提供创建对象的方法
- // 这里使用自己提供的 方法实例化对象, 不需要spring推断构造方法区实例化bean
- // genericBeanDefinition.setInstanceSupplier(() -> new IndexService(beanFactory.getBean(OrderSevice.class)));
- Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
- if (instanceSupplier != null) {
- return obtainFromSupplier(instanceSupplier, beanName);
- }
-
- //todo 这个程序员自己提供创建对象的工厂方法 factory-method
- if (mbd.getFactoryMethodName() != null) {
- //调用工厂方法实例化
- return instantiateUsingFactoryMethod(beanName, mbd, args);
- }
-
- // Shortcut when re-creating the same bean...
- //TODO 下面是重点 开始创建bean 使用容器的自动装配方法进行实例化
- //表示创建对象的构造方法没有被解析过
- boolean resolved = false;
- //是否需要自动注入
- boolean autowireNecessary = false;
- //args 一般都为空
- if (args == null) {
- synchronized (mbd.constructorArgumentLock) {
- //Todo 下面很重要 如果不为空 表示这个class 方法被解析过了 表示已经找到了创建对象的方式
- // 一般在原型模式中 使用 快捷方式,不需要再次解析构造方法
- if (mbd.resolvedConstructorOrFactoryMethod != null) {
- resolved = true;
- autowireNecessary = mbd.constructorArgumentsResolved;
- }
- }
- }
- if (resolved) {
- if (autowireNecessary) {
- //配置了自动装配属性,使用容器的自动装配实例化
- //容器的自动装配是根据参数类型匹配Bean的构造方法
- return autowireConstructor(beanName, mbd, null, null);
- }
- else {
- //使用默认的无参构造方法实例化
- return instantiateBean(beanName, mbd);
- }
- }
-
- // Need to determine the constructor...
- //TODO 第二次调用后置处理器推断构造方法 下面是单例对象的 使用Bean的构造方法进行实例化
- //找到 class 构造方法 特殊的算法
- /* TODO spring 通过构造方法实例化 bean的原理
- 实例化这个对象---首先要推断构造方法
- 这个分两种类型
- 1、手动注入
- 会在后置处理器中 找到实现 SmartInstantiationAwareBeanPostProcessor接口的类型
- AutowiredAnnotationBeanPostProcessor类中的determineCandidateConstructors 方法来推断出
- 合适的构造方法创建对象
- 1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
- 1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
- 1.3 如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
- 1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
- 1.5、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
- 1.6、多个构造方法 且多个构造方法加了@Autowired(required = false) 就把构造方法都加到集合中 第二次推断
- 2、自动注入 --通过构造方法自动注入
- 2.1、如果有多个构造方法 找出最优的构造器 参数最多的 为最优的
- */
- Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
- if (ctors != null ||
- mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
- mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
- //使用容器的自动装配特性,调用匹配的构造方法实例化
- //使用推断出来的构造方法找到一个可以用的 实例化bean
- return autowireConstructor(beanName, mbd, ctors, args);
- }
-
- // No special handling: simply use no-arg constructor.
- //使用默认的无参构造方法实例化
- return instantiateBean(beanName, mbd);
- }
接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
其中推断构造器的规则
这个分两种类型
1、手动注入
合适的构造方法创建对象
1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
1.3 如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
1.5、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
1.6、多个构造方法 且多个构造方法加了@Autowired(required = false) 就把构造方法都加到集合中 第二次推断2、自动注入 --通过构造方法自动注入
2.1、如果有多个构造方法 找出最优的构造器 参数最多的为最优的2.2、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
2.3、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
代码实现:
- protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
- throws BeansException {
-
- if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- // AutowiredAnnotationBeanPostProcessor 这个后置处理 实现了 SmartInstantiationAwareBeanPostProcessor
- if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
- SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
- //TODO 推断构造器 AutowiredAnnotationBeanPostProcessor
- Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
- if (ctors != null) {
- return ctors;
- }
- }
- }
- }
- return null;
- }
-
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
- //TODO 为自动依赖注入装配Bean选择合适的构造方法
- @Override
- @Nullable
- public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
- throws BeanCreationException {
-
- // Let's check for lookup methods here..
- if (!this.lookupMethodsChecked.contains(beanName)) {
- try {
- ReflectionUtils.doWithMethods(beanClass, method -> {
- Lookup lookup = method.getAnnotation(Lookup.class);
- if (lookup != null) {
- Assert.state(beanFactory != null, "No BeanFactory available");
- LookupOverride override = new LookupOverride(method, lookup.value());
- try {
- RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
- mbd.getMethodOverrides().addOverride(override);
- }
- catch (NoSuchBeanDefinitionException ex) {
- throw new BeanCreationException(beanName,
- "Cannot apply @Lookup to beans without corresponding bean definition");
- }
- }
- });
- }
- catch (IllegalStateException ex) {
- throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
- }
- this.lookupMethodsChecked.add(beanName);
- }
-
- //首先从容器的缓存中查找是否有指定Bean的构造方法
- // Quick check on the concurrent map first, with minimal locking.
- // candidateConstructorsCache 这个 class的构造方法的map
- Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
- if (candidateConstructors == null) {
- // Fully synchronized resolution now...
- //线程同步以确保容器中数据一致性
- synchronized (this.candidateConstructorsCache) {
- candidateConstructors = this.candidateConstructorsCache.get(beanClass);
- if (candidateConstructors == null) {
- Constructor<?>[] rawCandidates;
- try {
- //通过JDK反射机制,获取指定类的中所有声明的构造方法
- rawCandidates = beanClass.getDeclaredConstructors();
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName,
- "Resolution of declared constructors on bean Class [" + beanClass.getName() +
- "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
- }
- //存放候选中合格的构造方法的集合
- List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
- //autowire注解中required属性指定的构造方法
- Constructor<?> requiredConstructor = null;
- //默认的构造方法
- Constructor<?> defaultConstructor = null;
- //主构造方法 把推断的主要构造方法委托给 kotlin 非kotlin的类永远为空
- Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
- int nonSyntheticConstructors = 0;
- //遍历所有的构造方法,检查是否添加了autowire注解,以及是否指定了required属性
- for (Constructor<?> candidate : rawCandidates) {
- //判断是不是一个合成的类 一般不会进来
- if (!candidate.isSynthetic()) {
- nonSyntheticConstructors++;
- }
- else if (primaryConstructor != null) {
- continue;
- }
- //获取指定类中所有关于autowire的注解(Annotation)
- AnnotationAttributes ann = findAutowiredAnnotation(candidate);
- //如果指定类中没有antowire的注解
- if (ann == null) {
- Class<?> userClass = ClassUtils.getUserClass(beanClass);
- if (userClass != beanClass) {
- try {
- Constructor<?> superCtor =
- userClass.getDeclaredConstructor(candidate.getParameterTypes());
- ann = findAutowiredAnnotation(superCtor);
- }
- catch (NoSuchMethodException ex) {
- // Simply proceed, no equivalent superclass constructor found...
- }
- }
- }
- //如果指定类中有关于antowire的注解
- if (ann != null) {
- //如果antowire注解中指定了required属性
- if (requiredConstructor != null) {
- throw new BeanCreationException(beanName,
- "Invalid autowire-marked constructor: " + candidate +
- ". Found constructor with 'required' Autowired annotation already: " +
- requiredConstructor);
- }
- //获取autowire注解中required属性值
- boolean required = determineRequiredStatus(ann);
- //如果获取到autowire注解中required的属性值
- if (required) {
- //如果候选构造方法集合不为空
- if (!candidates.isEmpty()) {
- throw new BeanCreationException(beanName,
- "Invalid autowire-marked constructors: " + candidates +
- ". Found constructor with 'required' Autowired annotation: " +
- candidate);
- }
- //当前的构造方法就是required属性所配置的构造方法
- requiredConstructor = candidate;
- }
- //将当前的构造方法添加到哦啊候选构造方法集合中
- candidates.add(candidate);
- }
- //如果autowire注解的参数列表为空
- else if (candidate.getParameterCount() == 0) {
- defaultConstructor = candidate;
- }
- }
- //如果候选构造方法集合不为空
- if (!candidates.isEmpty()) {
- // Add default constructor to list of optional constructors, as fallback.
- //如果所有的构造方法都没有配置required属性,且有默认构造方法
- if (requiredConstructor == null) {
- if (defaultConstructor != null) {
- //将默认构造方法添加到候选构造方法列表
- candidates.add(defaultConstructor);
- }
- else if (candidates.size() == 1 && logger.isWarnEnabled()) {
- logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
- "': single autowire-marked constructor flagged as optional - " +
- "this constructor is effectively required since there is no " +
- "default constructor to fall back to: " + candidates.get(0));
- }
- }
- //将候选构造方法集合转换为数组
- candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
- }
- //TODO 这里是判断构造方法 是否只有一个有参构造 如果一个有参构造则 为有效的构造方法
- else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
- candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
- }
- //下面两个都不成立 primaryConstructor != null
- else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null) {
- candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
- }
- else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
- candidateConstructors = new Constructor<?>[] {primaryConstructor};
- }
- else {
- //如果候选构造方法集合为空,则创建一个空的数组
- candidateConstructors = new Constructor<?>[0];
- }
- //将类的候选构造方法集合存放到容器的缓存中
- this.candidateConstructorsCache.put(beanClass, candidateConstructors);
- }
- }
- }
- //返回指定类的候选构造方法数组,如果没有返回null
- return (candidateConstructors.length > 0 ? candidateConstructors : null);
- }
当推断出来使用默认无参构造
- //使用默认的无参构造方法实例化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 这里会再次推断构造方法实例化对象。
- public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
- @Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
-
- BeanWrapperImpl bw = new BeanWrapperImpl();
- this.beanFactory.initBeanWrapper(bw);
- //TODO 最后被确认使用的 构造方法
- Constructor<?> constructorToUse = null;
- //这里面存放的 构造方法的参数
- ArgumentsHolder argsHolderToUse = null;
- //最终确定的参数
- Object[] argsToUse = null;
-
- if (explicitArgs != null) {
- argsToUse = explicitArgs;
- }
- else {
- Object[] argsToResolve = null;
- synchronized (mbd.constructorArgumentLock) {
- //判断当前类 有没有解析构造方法 单例一般都为false
- constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
- //原型模式会走这个
- if (constructorToUse != null && mbd.constructorArgumentsResolved) {
- // Found a cached constructor...
- argsToUse = mbd.resolvedConstructorArguments;
- if (argsToUse == null) {
- argsToResolve = mbd.preparedConstructorArguments;
- }
- }
- }
- //转化 参数的属性值
- if (argsToResolve != null) {
- argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
- }
- }
- //这个单例模式的处理
- if (constructorToUse == null) {
- // Need to resolve the constructor.
- //判断是否需要自动注入
- boolean autowiring = (chosenCtors != null ||
- mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
- ConstructorArgumentValues resolvedValues = null;
- //构造方法参数个数的最小值
- int minNrOfArgs;
- //这个数根据传入参数做判断
- if (explicitArgs != null) {
- //表示实例spring 那个构造方法最少要多少
- minNrOfArgs = explicitArgs.length;
- }
- else {
- //获取构造方法的 参数
- ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
- //
- resolvedValues = new ConstructorArgumentValues();
- //得到构造方法参数个数的最小值
- //todo 这个一般为0 除非在实例化的时候
- /*
- GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("indexService");
- genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanFactory.getBean(UserServiceTest.class));
- */
- minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
- }
-
- // Take specified constructors, if any.
- //TODO 开始处理构造方法
- Constructor<?>[] candidates = chosenCtors;
- if (candidates == null) {
- Class<?> beanClass = mbd.getBeanClass();
- try {
- //拿到索引构造方法再次推断
- candidates = (mbd.isNonPublicAccessAllowed() ?
- beanClass.getDeclaredConstructors() : beanClass.getConstructors());
- }
- catch (Throwable ex) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Resolution of declared constructors on bean Class [" + beanClass.getName() +
- "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
- }
- }
- //todo 对构造方法进行排序
- // 排序规则 1、public 2、参数个数
- AutowireUtils.sortConstructors(candidates);
- //差异值
- int minTypeDiffWeight = Integer.MAX_VALUE;
- //模糊不清的构造方法
- Set<Constructor<?>> ambiguousConstructors = null;
- LinkedList<UnsatisfiedDependencyException> causes = null;
-
- for (Constructor<?> candidate : candidates) {
- Class<?>[] paramTypes = candidate.getParameterTypes();
- // TODO 最终使用的 如果找到一个就直接退出了 最重要的条件 argsToUse.length > paramTypes.length
- if (constructorToUse != null && argsToUse.length > paramTypes.length) {
- // Already found greedy constructor that can be satisfied ->
- // do not look any further, there are only less greedy constructors left.
- break;
- }
- if (paramTypes.length < minNrOfArgs) {
- continue;
- }
- //最后要使用的参数
- ArgumentsHolder argsHolder;
- if (resolvedValues != null) {
- //得到当前构造方法的参数名字
- try {
- String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
- if (paramNames == null) {
- ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
- if (pnd != null) {
- paramNames = pnd.getParameterNames(candidate);
- }
- }
- //TODO
- argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
- getUserDeclaredConstructor(candidate), autowiring);
- }
- catch (UnsatisfiedDependencyException ex) {
- if (this.beanFactory.logger.isTraceEnabled()) {
- this.beanFactory.logger.trace(
- "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
- }
- // Swallow and try next constructor.
- if (causes == null) {
- causes = new LinkedList<>();
- }
- causes.add(ex);
- continue;
- }
- }
- else {
- // Explicit arguments given -> arguments length must match exactly.
- if (paramTypes.length != explicitArgs.length) {
- continue;
- }
- argsHolder = new ArgumentsHolder(explicitArgs);
- }
- //计算差异值 -1024
- int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
- argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
- // Choose this constructor if it represents the closest match.
- if (typeDiffWeight < minTypeDiffWeight) {
- constructorToUse = candidate;
- argsHolderToUse = argsHolder;
- argsToUse = argsHolder.arguments;
- minTypeDiffWeight = typeDiffWeight;
- ambiguousConstructors = null;
- }
- //模糊不清楚的 两个构造方法算法一样 会随机选择一个
- else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
- if (ambiguousConstructors == null) {
- ambiguousConstructors = new LinkedHashSet<>();
- ambiguousConstructors.add(constructorToUse);
- }
- //模糊不清楚的
- ambiguousConstructors.add(candidate);
- }
- }
- //如果没有找到处理异常
- if (constructorToUse == null) {
- if (causes != null) {
- UnsatisfiedDependencyException ex = causes.removeLast();
- for (Exception cause : causes) {
- this.beanFactory.onSuppressedException(cause);
- }
- throw ex;
- }
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Could not resolve matching constructor " +
- "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
- }
- //mbd.isLenientConstructorResolution() 宽松模式
- else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Ambiguous constructor matches found in bean '" + beanName + "' " +
- "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
- ambiguousConstructors);
- }
-
- if (explicitArgs == null) {
- //todo
- argsHolderToUse.storeCache(mbd, constructorToUse);
- }
- }
-
- try {
- final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
- Object beanInstance;
-
- if (System.getSecurityManager() != null) {
- final Constructor<?> ctorToUse = constructorToUse;
- final Object[] argumentsToUse = argsToUse;
- beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
- strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
- beanFactory.getAccessControlContext());
- }
- else {
- beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
- }
-
- bw.setBeanInstance(beanInstance);
- return bw;
- }
- catch (Throwable ex) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Bean instantiation via constructor failed", ex);
- }
- }
实例化后会第三和第四调用后置处理器
这里主要解决 处理合并BeanDefinition的问题
入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
接口:这个后置处理器 需要实现 MergedBeanDefinitionPostProcessor 接口中的postProcessMergedBeanDefinition方法
1、合并相关介绍:
为什么会提前合并 下面代码
通过类型找到名字---返回一个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);
- }
- }
- }
1.1 、实现类:AutowiredAnnotationBeanPostProcessor
- @Override
- public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
- //
- InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
- metadata.checkConfigMembers(beanDefinition);
- }
1.2、实现类:CommonAnnotationBeanPostProcessor
- @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的后置处理器不一样的。
这个工厂是一个lambda表达式,在出现循环依赖的时候执行
重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象;
地址:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference(beanName, mbd, bean)
- //向容器中缓存单例模式的Bean对象,以防循环引用
- //TODO 判断是否允许循环依赖
- boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
- isSingletonCurrentlyInCreation(beanName));
- if (earlySingletonExposure) {
- if (logger.isDebugEnabled()) {
- logger.debug("Eagerly caching bean '" + beanName +
- "' to allow for resolving potential circular references");
- }
- //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
- //TODO 第四调用后置处理器
- // 重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象
- addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
- }
接口: SmartInstantiationAwareBeanPostProcessor# getEarlyBeanReference
- protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
- Object exposedObject = bean;
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
- SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
- exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
- }
- }
- }
- return exposedObject;
- }
实现类:AbstractAutoProxyCreator #getEarlyBeanReference
下面是添加到二级缓存中
- @Override
- public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
- Object cacheKey = getCacheKey(bean.getClass(), beanName);
- if (!this.earlyProxyReferences.contains(cacheKey)) {
- this.earlyProxyReferences.add(cacheKey);
- }
- return wrapIfNecessary(bean, beanName, cacheKey);
- }
这个阶段主要判断当前实例化的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 实例化生命周期示例
- *
- * @Author: dukun0210
- * @Date: 2021/2/17 19:23
- */
- 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;//这里表示什么都不变化
- }
- }
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。