BaldHead`s Blog

浅谈spring-createBean

找到BeanClass并且加载类

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		// 找到需要创建 Bean 对应的 Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
  .......省略与此步骤无关的代码
}

注意:上面代码中的 resolveBeanClass(mbd, beanName) 方法,就是去查找BeanClass的,下面看看 resolveBeanClass 方法的代码

@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
      throws CannotLoadBeanClassException {

   try {
      // 判断 BeanDefinition 中的 beanClass 属性是不是 Class 类型的
      if (mbd.hasBeanClass()) {
         return mbd.getBeanClass();
      }
      // 执行搜索 Bean class
      return doResolveBeanClass(mbd, typesToMatch);
   }  ...省略catch 代码
   }
}

注意代码中有一个 mbd.hasBeanClass() 的判断, 这个地方比较有迷惑性,并不是判断beanClass属性是否存在,而是判断

beanClass 属性是不是属于 Class类型的,因为在spring最开始的扫描过程中,给BeanDefiniton 中 beanClass 属性存入的是对应 BeanDefinition 的类名称,下面是 hasBeanClass() 方法的代码:

public boolean hasBeanClass() {

   // 判断 BeanDefinition 中的 beanClass 属性是不是属于 Class 的
   // 因为最开始的时候存入的是 BeanDefinition 对应的类的类名
   return (this.beanClass instanceof Class);
}

如果判断 beanClass 属性 是一个CLass 对象则直接返回,否则进入doResolceBeanClass(mad, typesToMatch) 方法

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
      throws ClassNotFoundException {

   // 获取类加载器
   ClassLoader beanClassLoader = getBeanClassLoader();
   ClassLoader dynamicLoader = beanClassLoader;
   boolean freshResolve = false;

   .... 省略代码
     
   // 这里就是拿的 RootBeanDefinition 中的 beanClass属性
   String className = mbd.getBeanClassName();
   if (className != null) {
      // 解析 spring 自己定义的表达式---没有去了解
      Object evaluated = evaluateBeanDefinitionString(className, mbd);
      if (!className.equals(evaluated)) {
         // A dynamically resolved expression, supported as of 4.2...
         if (evaluated instanceof Class) {
            return (Class<?>) evaluated;
         } else if (evaluated instanceof String) {
            className = (String) evaluated;
            freshResolve = true;
         } else {
            throw new IllegalStateException("Invalid class name expression result: " + evaluated);
         }
      }
      if (freshResolve) {
         // When resolving against a temporary class loader, exit early in order
         // to avoid storing the resolved Class in the bean definition.
         if (dynamicLoader != null) {
            try {
               // 加载类,当前 需要创建的 Bean 的 Class文件
               return dynamicLoader.loadClass(className);
            } catch (ClassNotFoundException ex) {
               if (logger.isTraceEnabled()) {
                  logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
               }
            }
         }
        	// 内部 使用了 Class.forName() 去加载这个类:Class.forName(name, false, clToUse);
         return ClassUtils.forName(className, dynamicLoader);
      }
   }
   // 定期解析,将结果缓存在 BeanDefinition 中
   // Resolve regularly, caching the result in the BeanDefinition...
   return mbd.resolveBeanClass(beanClassLoader);
}

首先我们注意到方法进入时就有一个获取BeanClassLoader的方法 getBeanClassLoader(),最终该方法的代码是如下:

@Nullable
public static ClassLoader getDefaultClassLoader() {
   ClassLoader cl = null;
   try {
      // 获取当前线程的类加载器,可以设置的 Thread.currentThread().setContextClassLoader();
      cl = Thread.currentThread().getContextClassLoader();
   }
   catch (Throwable ex) {
      // Cannot access thread context ClassLoader - falling back...
   }
  // 使用当前类的加载器去加载,有可能返回空,因为 lib 下面的 jar包使用 bootstrap 类加载器去加载的
   if (cl == null) {
      // No thread context class loader -> use class loader of this class.
      cl = ClassUtils.class.getClassLoader();
      if (cl == null) {
         // getClassLoader() returning null indicates the bootstrap ClassLoader
         try {
            // 获取系统的加载器
            cl = ClassLoader.getSystemClassLoader();
         }
         catch (Throwable ex) {
            // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
         }
      }
   }
   return cl;
}

就是拿到类加载器,最终就是使用当前的类加载器,去加载mbd.getBeanClassName()方法拿出来的类名称className

image-20220710164128575

这样将 BeanClass 文件就已经被加载了,紧接着就是进入实例化,在实例化前,还有一个步骤就是:实例化前

实例化前

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

	...... 省略上一步骤的代码

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      // 实例化前  InstantiationAwareBeanPostProcessor  使用的是这个 BeanPostprocessor
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      // 如果实例化前,由自己创建类对象则直接返回
      if (bean != null) {
         return bean;
      }
   }
  	// doCreateBean 执行创建bean的方法,此方法中就会去实例化对象
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		... 省略日志打印
			return beanInstance;
  ..... 省略此步骤无关代码
}

这里主要关注的就是实例化前的 InstantiationAwareBeanPostProcessor 接口,接口中有三个默认的方法,这里只讨论,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 初始化前的方法

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
  .... 省略另外两个方法
}

该方法的执行时机就是在实例化前,从给出的createBean方法源码中可以体现出来,这里就给了我们许多的操作空间。

resolveBeforeInstantiation(beanName, mbdToUse); 在这个方法里面就回去执行初始化前的调用:

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.
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            // 在实例化前应用BeanPostProcessor
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               // 初始化后的 BeanPostProcessor
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

可以看到在初始化前调用之后判断了一次 返回的 bean对象是不是空,因为在初始化前方法中给传入BeanClass 对象,在此之前就已经给 beanClass 赋值过了,这里我们可以自己去创建一个对象返回,如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。在执行实例化前这里还有一个小的知识,就是当同时存在很多的实例化前 postProcessor ,只要一直行到 postProcessBeforeInstantiation 方法返回的bean不是空的的情况下,剩下所有的 初始化前postProcessor都不会在执行了。

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 这里拿到的就是 InstantiationAwareBeanPostProcessor 类型的 postProcessor
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			// 因为这里是初始化前,所以在执行到 beanPostprocessor 返回有对象的时候就直接返回,不会执行后续的 InstantiationAwareBeanPostProcessor
			// 如果第一个处理器就返回了 对象实例,则不会再去执行其他的 InstantiationAwareBeanPostProcessor
			if (result != null) {
				return result;
			}
		}
		return null;
	}

在for循环中 getBeanPostProcessorCache().instantiationAware方法拿到的就是,InstantiationAwareBeanPostProcessor类型的postProcessor,原因是:spring对postProcessor进行了分类的:

image-20220710171030305

下面进入 doCreatebean() 中初始化的流程

实例化

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   // BeanWrapper:持有创建出来的Bean
   BeanWrapper instanceWrapper = null;
   // 判断当前的bean定义是否为单例
   if (mbd.isSingleton()) {
      // 有可能在本 Bean 创建之前就已经把当前 Bean 给创建出来了(比如在依赖注入过程中)
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 从工厂bean缓存中移除
   }// 不为空则  代表为 FactoryBean 已经创建过,存在缓存中
   if (instanceWrapper == null) {
      /**
       * 创建bean的实例,默认使用无参构造器
       * 实例化但是并未初始化,就是没有给bean的属性复制
       * 组建的原始对象就创建了
       */
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   // 允许(MergedBeanDefinitionPostProcessor)增强器修改合并的bean definition 修改BD信息
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }
  ...... 省略代码 ......
}

createBeanInstance(beanName, mbd, args);此方法就是去创建 bean 的实例;

此处还有一个 应用增强器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)根据名称可以知道这是一个操作BeanDefinition的增强器,可以去修改BeanDefinition中的属性,但是注意这个的执行时机,是在 bean 实例化之后在执行的,所以说现在修改 BeanDefiniton的有些属性是无效的,比如beanClss属性,因为bean已经创建了。

此处的 PostProcessor的类型为:MergedBeanDefinitionPostProcessor

Supplier创建对象

首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // 拿到bean 的 class  Make sure bean class is actually resolved at this point.
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   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());
   }
   // 定义bean的提供者  ,存在就使用提供者创建对象:这是一个函数式接口
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
     	// 存在 bean 的提供者,则直接调用 Supplier 的 get() 方法拿到对象
			return obtainFromSupplier(instanceSupplier, beanName);
   }
 // 使用工厂方法、例如:@Bean注解放在方法上,返回值注入容器,spring 会认为这是一个工厂方法
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		// 后置处理器 SmartInstantiationAwareBeanPostProcessor 有机会决定在创建对象钱使用那个构造器 Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args); //有自己指定的构造器: 构造器方式的自动注入
		}

		// 使用默认的自己设置的高优先级的 构造器 Preferred constructors for default construction? // 拿到构造器
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}
		// 默认使用无参构造器
		// No special handling: simply use no-arg constructor. 无需特殊处理:使用简单的无参构造器
		return instantiateBean(beanName, mbd);
}

image-20220710184048620

工厂方法创建对象

方法一

如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod,比如:

<bean id="userService" class="cn.baldhead.service.UserService" factory-method="createUserService" />

对应的UserService 代码

public class UserService {

	public static UserService createUserService() {
		System.out.println("执行createUserService()");
		UserService userService = new UserService();
		return userService;
	}

	public void test() {
		System.out.println("test");
	}

}

方法二

<bean id="commonService" class="cn.baldhead.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />

Spring发现当前BeanDefinition方法设置了工厂方法后,就会区分这两种方式,然后调用工厂方法得到对象。

值得注意的是,我们通过@Bean所定义的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常类似,@Bean所注解的方法就是factoryMethod,AppConfig对象就是factoryBean。如果@Bean所所注解的方法是static的,那么对应的就是方式一。

推断构造方法

推断完构造方法后,就会使用构造方法来进行实例化了。

额外的,在推断构造方法逻辑中除开会去选择构造方法以及查找入参对象意外,会还判断是否在对应的类中是否存在使用@Lookup注解了方法。如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。

@Lookup注解就是方法注入,例如demo如下:

@Component
public class UserService {

	private OrderService orderService;

	public void test() {
		OrderService orderService = createOrderService();
		System.out.println(orderService);
	}

	@Lookup("orderService")
	public OrderService createOrderService() {
		return null;
	}

}

在实例化时,如果判断出来当前BeanDefinition中没有LookupOverride,那就直接用构造方法反射得到一个实例对象。如果存在LookupOverride对象,也就是类中存在@Lookup注解了的方法,那就会生成一个代理对象。

BeanDefionition 的后置处理

Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工,比如:

@Component
public class BaldHeadMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 可以手动给 beanDefinition 得ptopertyValues 添加一个属性赋值,属性名-值(bean中的属性赋值)
		if ("baldHeadService".equals(beanName)) {
			beanDefinition.getPropertyValues().add("orderService", new OrderService());
		}
	}
}

源码在--doCreateBean()

/ Allow post-processors to modify the merged bean definition.
		// 允许(MergedBeanDefinitionPostProcessor)增强器修改合并的bean definition 修改BD信息
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

在Spring源码中,AutowiredAnnotationBeanPostProcessor就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)。

实例化后

AbstractAutowireCapableBeanFactory.poputlateBean()

// 设置属性注入   之前bean的状态,例如,属性赋值之前后置处理器可以提前处理些东西
// 支持字段注入  (但是在此处什么事都没做)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
      if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
         return;
      }
   }
}

属性填充

AbstractAutowireCapableBeanFactory.populateBean()

spring的注入

​ 必须要有对应属性的set方法,type:根据参数的类型去找到对应的Bean,name:根据方法setxxx后面的一串去找到对应的 Bean ,例如当前就是用的 xxx 作为name去找

只要是set 方法 Spring 都会去调用,不管这个set方法是做什么的,都会去调用

​ BY_TYPE,BY_NAME

	// 获取所有属性的值
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable. 通过名称自动注入参数的值
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable. 通过类型注入参数的值
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

自动注入

处理属性

这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过InstantiationAwareBeanPostProcessor.postProcessProperties()扩展点来实现的,比如我们甚至可以实现一个自己的自动注入功能,比如:

@Component
public class BaldHeadInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			for (Field field : bean.getClass().getFields()) {
				if (field.isAnnotationPresent(BaldHeadInject.class)) {
					field.setAccessible(true);
					try {
						field.set(bean, "123");
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
		}

		return pvs;
	}
}

Aware回调

AbstractAutowireCapableBeanFactory.initializeBean(..);

回调执行Aware接口

完成了属性赋值之后,Spring会执行一些回调,包括:

  1. BeanNameAware:回传beanName给bean对象。
  2. BeanClassLoaderAware:回传classLoader给bean对象。
  3. BeanFactoryAware:回传beanFactory给对象。

初始化前

初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization(),比如

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			System.out.println("初始化前");
		}

		return bean;
	}
}

利用初始化前,可以对进行了依赖注入的Bean进行处理。

在Spring源码中:

  1. InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,

  2. ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:

    1. EnvironmentAware:回传环境变量
    2. EmbeddedValueResolverAware:回传占位符解析器
    3. ResourceLoaderAware:回传资源加载器
    4. ApplicationEventPublisherAware:回传事件发布器
    5. MessageSourceAware:回传国际化资源
    6. ApplicationStartupAware:回传应用其他监听对象,可忽略
    7. ApplicationContextAware:回传Spring容器ApplicationContext
  3. @PostConstruct @PreDestory 也是在初始化前这一步进行的解析,并做了一个缓存

  4. InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata()

  5. 	private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    		if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
    			return this.emptyLifecycleMetadata;
    		}
    
            // 这里面就会有 @PostConstruct 的,并且初始化方法有先后执行顺序,父类的排在前面,子类的在后面
            // 父类优先执行
    		List<LifecycleElement> initMethods = new ArrayList<>();
            // 这里面会有 @PreDestroy 的
    		List<LifecycleElement> destroyMethods = new ArrayList<>();
    		Class<?> targetClass = clazz;
    
    		do {
    			final List<LifecycleElement> currInitMethods = new ArrayList<>();
    			final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
    
    			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
    				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
    					LifecycleElement element = new LifecycleElement(method);
    					currInitMethods.add(element);
    					if (logger.isTraceEnabled()) {
    						logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
    					}
    				}
    				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
    					currDestroyMethods.add(new LifecycleElement(method));
    					if (logger.isTraceEnabled()) {
    						logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
    					}
    				}
    			});
    			// 父类的初始化方法在前,也就是有一个先后顺序,先执行父类的 init-method 方法
    			initMethods.addAll(0, currInitMethods);
    			destroyMethods.addAll(currDestroyMethods);
    			targetClass = targetClass.getSuperclass();
    		}
    		while (targetClass != null && targetClass != Object.class);
    
    		return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
    				new LifecycleMetadata(clazz, initMethods, destroyMethods));
    	}
    

初始化

  1. 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    			throws Throwable {
    		// 检查是否实现了 InitializingBean 接口
    		boolean isInitializingBean = (bean instanceof InitializingBean);
    		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    			}
    			// 实现了 InitializingBean 接口,执行调用 afterPropertiesSet 方法
    			// 使用了多态的操作方式 将 bean 转换为一个接口(initializingBean)
    			((InitializingBean) bean).afterPropertiesSet();
    		}
    
    		if (mbd != null && bean.getClass() != NullBean.class) {
    			// 获取自定一个init-method方法
    			String initMethodName = mbd.getInitMethodName();
    			if (StringUtils.hasLength(initMethodName) &&
    					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    					!mbd.isExternallyManagedInitMethod(initMethodName)) {
    				// 执行自定一个init-method方法,通过反射 method.invoke()
    				invokeCustomInitMethod(beanName, bean, mbd);
    			}
    		}
    	}
    
  2. 执行BeanDefinition中指定的初始化方法

    mbd.getInitMethodName()

初始化后

spring在初始化后也提供了一个扩展点,BeanPostProcessor.postProcessAfterInitialization()->例如:

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if ("baldHeadService".equals(beanName)) {
			System.out.println("初始化后");
		}

		return bean;
	}
}
if (mbd == null || !mbd.isSynthetic()) { // 初始化后执行,postProcessor
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象

总结BeanPostProcessor

  1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
  2. 实例化
  3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
  4. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  5. 自动注入
  6. InstantiationAwareBeanPostProcessor.postProcessProperties()
  7. Aware对象
  8. BeanPostProcessor.postProcessBeforeInitialization()
  9. 初始化
  10. BeanPostProcessor.postProcessAfterInitialization()

bean的销毁

目前这一块未总结
如文中又错误请指出或者联系我:tianxiang.deng@foxmail.com

posted @ 2022-07-22 09:24  BaldHead  阅读(478)  评论(0编辑  收藏  举报