Spring Bean 生命周期二
[TOC]
Chapter 6 Spring Bean 实例化阶段
1 AbstractAutowireCapableBeanFactory#doCreateBean
该方法为创建 Bean, createBeanInstance 则为创建 Bean 的实例的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 实例化 bean。
BeanWrapper instanceWrapper = null;
// RootBeanDefinition 是单例作用域
if (mbd.isSingleton()) {
// 移除缓存,并返回移除对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// bean 的包装器 == null
if (instanceWrapper == null) {
// 创建 Bean 的包装器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
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;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
2 AbstractAutowireCapableBeanFactory#createBeanInstance
determineConstructorsFromBeanPostProcessors 该方法作用为从扩展器列表中决定使用的构造器列表 用户可以自己去扩展 SmartInstantiationAwareBeanPostProcessor 接口,返回构造器列表 createBeanInstance 方法的参数解析:
- String beanName bean 的名称
- RootBeanDefinition mbd bean 定义
- @Nullable Object[] args 构造参数列表,可以为空
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 通过 BeanClassName 去解析 Bean 对应的 Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 对类的权限做验证,如果不是 public 修饰的类,则抛出异常
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());
}
// 函数式接口,先忽略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// RootBeanDefinition 是否配置了 工厂方法
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) {
// 解析标识变为 true
resolved = true;
// 是否需要自动注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 是否已经解析过
// resolved == true 的场景为,当类的作用域为 prototype 时,重复去依赖查找或者依赖注入时,都是获取新的对象,
// 但是 Bean 定义都是不变的,这里直接进行之前的解析情况进行 Bean 的实例化
// 减少了构造参数的确定,性能优化
if (resolved) {
if (autowireNecessary) {
// 通过构造参数自动创建
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 默认的无参构造创建 Bean 实例
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 从 Bean 的扩展中去确定构造器列表
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// ctors != null 构造方法不为空
// mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR 解析模式为构造器自动注入
// mbd.hasConstructorArgumentValues() 有构造器参数
// !ObjectUtils.isEmpty(args) 传递的构造器参数不为空
// 以上四种情况都会走入构造器注入
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.
// 普通的 Bean 实例化
return instantiateBean(beanName, mbd);
}
3 AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors
/**
* 确定用于给定 bean 的候选构造函数,检查所有已注册的
*/
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
4 AbstractAutowireCapableBeanFactory#instantiateBean
getInstantiationStrategy 获取实例化策略。
InstantiationStrategy 是实例化的策略接口,策略的实现为: CglibSubclassingInstantiationStrategy 和 SimpleInstantiationStrategy, CglibSubclassingInstantiationStrategy 策略又继承了 SimpleInstantiationStrategy 类。 这里调用 instantiationStrategy#instantiate 方法,但是 CglibSubclassingInstantiationStrategy 中没有重写 instantiate 方法,所以,调用的还是 SimpleInstantiationStrategy 中的实例化方法
/** 创建 bean 实例的策略。默认采用 CGLIB 策略 */
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
// Java 安全管理
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 根据相应的策略类去创建 Bean 实例
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 将 bean 实例 转化为 Bean 包装类
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
// 初始化 Bean 的包装类
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
5 SimpleInstantiationStrategy#instantiate
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 不存在方法定义的覆盖
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获取 RootBeanDefinition 的解析构造器或者工厂方法
// 首次进来为空
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 获取 beanClass
final Class<?> clazz = bd.getBeanClass();
// 如果 beanClass 为接口,则抛出异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 赋值 constructorToUse = bean 的构造器
constructorToUse = clazz.getDeclaredConstructor();
}
// 再赋值给 resolvedConstructorOrFactoryMethod
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 根据构造器实例化 Bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 走方法注入
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
6 BeanUtils#instantiateClass
BeanUtils Bean 操作的工具类
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 设置构造器的权限为true
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
// 获取参数的类型列表
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
// 创建参数数组
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
// 如果参数为空
if (args[i] == null) {
// 获取参数的类型
Class<?> parameterType = parameterTypes[i];
// 如果是包装类,则为null,如果是基础类型,则为对应包装类型的默认值
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
// 不为空的情况下直接赋值
argsWithDefaultValues[i] = args[i];
}
}
// 调用反射创建 Bean 的实例
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
7 AbstractAutowireCapableBeanFactory#autowireConstructor
构造器注入方法,这里创建了一个构造器处理器来执行自动注入操作
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
8 ConstructorResolver#autowireConstructor
参数解析:
- String beanName bean名称
- RootBeanDefinition mbd bean定义
- @Nullable Constructor<?>[] chosenCtors 从 BeanPostProcessors 中获取的构造器列表
- @Nullable Object[] explicitArgs XML 中配置的 里面配置的参数
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
// 创建 Bean 的包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化 Bean 的包装器
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 显示的构造器参数(即 XML 中配置的)
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 获取 RootBeanDefinition 上的已经解析好的构造方法或者工厂方法,首次为 null
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, true);
}
}
// 需要用的构造器和构造器参数都为空的时候执行
if (constructorToUse == null || argsToUse == null) {
//采用指定的构造函数,如果有的话。
Constructor<?>[] candidates = chosenCtors;
// 指定构造器为空
if (candidates == null) {
// 获取 beanClass
Class<?> beanClass = mbd.getBeanClass();
try {
// 返回是否允许访问非公共构造函数和方法 ? 获取所有构造方法 : 获取所有 public 的构造方法
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);
}
}
// 只有一个构造器候选者 && 没有设置构造器参数 && 拥有构造器标识也为 null
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
// 获取唯一的构造器
Constructor<?> uniqueCandidate = candidates[0];
// 如果构造器没有参数
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 将构造器添加到已经解析的构造器或者工厂方法记录中
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
// 构造器参数已经解析标识更新
mbd.constructorArgumentsResolved = true;
// 赋值构造器参数
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
// 设置实例
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 当传递的构造器列表存在或者 RootBeanDefinition 的类型为构造器自动注入时,需要解析构造函数。
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 构造器参数列表
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
// 存在显示的构造器参数
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 将此 bean 的构造函数参数解析为 resolvedValues 对象。这可能涉及查找其他 bean
// 参数的最小长度
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 将构造器进行排序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历所有构造器候选者
for (Constructor<?> candidate : candidates) {
// 获取构造器参数数量
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// 已经找到满足条件的构造器了,直接结束
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
// 获取构造器参数类型集合
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
// 获取构造器参数名称列表,如果构造器上标注了 ConstructorProperties 注解
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
// 从参数名称发现器中获取 beanName
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 创建参数数组
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
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 (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 返回是在宽松模式还是在严格模式下解析构造函数。
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果它代表最接近的匹配,则选择此构造函数。
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)");
}
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 && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// bean 包装器设置实例
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
9 ConstructorPropertiesChecker#evaluate
private static class ConstructorPropertiesChecker {
@Nullable
public static String[] evaluate(Constructor<?> candidate, int paramCount) {
// 构造器上获取 ConstructorProperties 注解
ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class);
// 如果找到了
if (cp != null) {
// 获取结果
String[] names = cp.value();
if (names.length != paramCount) {
throw new IllegalStateException("Constructor annotated with @ConstructorProperties but not " +
"corresponding to actual number of parameters (" + paramCount + "): " + candidate);
}
return names;
}
else {
// 返回空
return null;
}
}
}
10 PrioritizedParameterNameDiscoverer#getParameterNames
@Override
@Nullable
public String[] getParameterNames(Constructor<?> ctor) {
for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) {
String[] result = pnd.getParameterNames(ctor);
if (result != null) {
return result;
}
}
return null;
}
11 ConstructorResolver#createArgumentArray
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
}
else {
// 如果是构造方法,则添加构造方法参数,如果是普通方法,则添加普通方法参数
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
}
else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
// 解析自动注入的对象,会调用依赖注入去找到构造方法对应的参数对象,会优先获取 primary 标注的对象
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
// 为给定的bean注册一个依赖bean,*在给定的bean被销毁之前被销毁
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
12 ConstructorResolver#resolveAutowiredArgument
用于解析应该自动装配的指定参数的模板方法
/**
* Template method for resolving the specified argument which is supposed to be autowired.
*/
@Nullable
protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
@Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
// 获取参数类型
Class<?> paramType = param.getParameterType();
if (InjectionPoint.class.isAssignableFrom(paramType)) {
InjectionPoint injectionPoint = currentInjectionPoint.get();
if (injectionPoint == null) {
throw new IllegalStateException("No current InjectionPoint available for " + param);
}
return injectionPoint;
}
try {
// 调用 beanFactory 的 resolveDependency 方法,该方法在前面的章节中已经讲过,可以回顾到之前的章节
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
}
catch (NoUniqueBeanDefinitionException ex) {
throw ex;
}
catch (NoSuchBeanDefinitionException ex) {
if (fallback) {
// Single constructor or factory method -> let's return an empty array/collection
// for e.g. a vararg or a non-null List/Set/Map parameter.
if (paramType.isArray()) {
return Array.newInstance(paramType.getComponentType(), 0);
}
else if (CollectionFactory.isApproximableCollectionType(paramType)) {
return CollectionFactory.createCollection(paramType, 0);
}
else if (CollectionFactory.isApproximableMapType(paramType)) {
return CollectionFactory.createMap(paramType, 0);
}
}
throw ex;
}
}
Chapter 7 Spring Bean 实例化后阶段
1 实例化后扩展阶段
实现 InstantiationAwareBeanPostProcessor 接口,并重写 postProcessAfterInstantiation 方法,该方法有两个参数:
- Object bean 当前正在创建的 Bean
- String beanName bean 的名称
- Return boolean 如果该值返回的是 false,则代表当前 bean 在后续不需要进行属性值的填充,在该方法中进行填充,如果返回的是 true,则继续执行后续填充属性的流程。
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.util.ObjectUtils;
/**
* @ClassName BeforeInstantiationBeanLifeCycleDemo
* @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
* @Author WQ
* @Date 2022/8/11 18:05
* @Version 1.0
*/
public class InstantiationBeanLifeCycleDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
reader.loadBeanDefinitions(locations);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}
static class ChildUserInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
// ChildUser childUser = new ChildUser();
// childUser.setAge(22);
// return childUser;
// }
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
User user = (User) bean;
user.setId(815L);
user.setName("小幸运");
return false;
}
return true;
}
}
}
2 postProcessAfterInstantiation 源码分析
- mbd.isSynthetic() 这里会判断 bean 是否为应用系统所创建, 一般为 false。
- hasInstantiationAwareBeanPostProcessors() 是否具有 AwareBeanPostProcessors 扩展实现。 ibp.postProcessAfterInstantiation 调用扩展实现的方法,如果返回的是 false 则直接结束 populateBean() 方法,结束赋值阶段。 返回 true 则继续向下执行 populateBean 执行属性赋值。
该源码分析在 AbstractAutowireCapableBeanFactory#populateBean 方法中进行属性填充的部分代码片段
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
Chapter 8 Spring Bean 属性赋值前阶段
1 概述
Bean 属性值元信息
- PropertyValues 属性的元信息,即存储属性值,在构造器里的话就是 ConstructorValues Bean 属性赋值前回调
- Spring 1.2 - 5.0:InstantiationAwareBeanPostProcessor#postProcessPropertyValues
- Spring 5.1:InstantiationAwareBeanPostProcessor#postProcessProperties
2 属性赋值前阶段,修改属性值示例
该声明周期主要处于实例化对象后阶段,属性赋值前阶段的中间阶段。 主要作用为:可以提前修改配置的属性,这样在属性赋值时,就不会采用配置的属性。 注意事项:如果在实例化对象后阶段,已经返回 false,终止掉了后续属性赋值流程,则 postProcessProperties 方法并不会被调用。
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.util.ObjectUtils;
/**
* @ClassName BeforeInstantiationBeanLifeCycleDemo
* @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
* @Author WQ
* @Date 2022/8/11 18:05
* @Version 1.0
*/
public class InstantiationBeanLifeCycleDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
reader.loadBeanDefinitions(locations);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}
static class ChildUserInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
// ChildUser childUser = new ChildUser();
// childUser.setAge(22);
// return childUser;
// }
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
User user = (User) bean;
user.setId(815L);
user.setName("小幸运");
return false;
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
final MutablePropertyValues propertyValues;
if (pvs instanceof MutablePropertyValues) {
propertyValues = (MutablePropertyValues) pvs;
} else {
propertyValues = new MutablePropertyValues();
}
propertyValues.add("number", "1111");
propertyValues.removePropertyValue("description");
propertyValues.addPropertyValue("description", "this is a description V2");
return propertyValues;
}
return null;
}
}
}
3 AbstractAutowireCapableBeanFactory#populateBean
AbstractAutowireCapableBeanFactory#populateBean 部分代码段实现了 Spring Bean 属性赋值前阶段对属性的修改操作 实例化后阶段,如果 postProcessAfterInstantiation 方法返回了 false, 则 populateBean Bean 属性填充就此结束。
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 如果这里 postProcessAfterInstantiation 方法返回了 false, 属性填充就终止掉了
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 获取 PropertyValues 属性元信息
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 解析自动注入模式(1-根据名称、2-根据类型、3-根据构造器)
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;
}
// 是否有 InstantiationAwareBeanPostProcessors 实现类标识
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// Bean 属性赋值前阶段,如果返回的 PropertyValues 有值,代表该方法已经修改了属性值
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 运行属性值填充 Bean 实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
Chapter 9 Spring Bean Aware接口回调阶段
1 概述
Spring Aware 接口
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- EnvironmentAware
- EmbeddedValueResolverAware
- ResourceLoaderAware
- ApplicationEventPublisherAware
- MessageSourceAware
- ApplicationContextAware
Aware 接口是 Spring 提供的回调接口,该接口只能使用 Spring 已存在的扩展,不允许用户自己扩展。 以 BeanNameAware 接口来说,该接口可以回调注入 BeanName。 BeanFactoryAware 则可以回调注入一个 BeanFactory
2 UserHolder
需要注入 Spring 中的 Bean, 实现了 BeanFactory 的 Aware 接口和 ApplicationContext 所属下的 Aware 接口。
package com.geekbang.thinking.in.spring.bean.lifecycle.domain;
import com.geekbang.spring.ioc.container.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringValueResolver;
/**
* @ClassName UserHolder
* @Description TODO
* @Author WQ
* @Date 2022/8/12 14:46
* @Version 1.0
*/
public class UserHolder implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware {
private User user;
private Integer number;
private String description;
private String beanName;
private ClassLoader classLoader;
private BeanFactory beanFactory;
private EmbeddedValueResolver resolver;
private Environment environment;
private ResourceLoader resourceLoader;
public UserHolder(User user) {
this.user = user;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "UserHolder{" +
"user=" + user +
", number=" + number +
", description='" + description + '\'' +
", beanName='" + beanName + '\'' +
", classLoader=" + classLoader +
", beanFactory=" + beanFactory +
", resolver=" + resolver +
", environment=" + environment +
", resourceLoader=" + resourceLoader +
'}';
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.resolver = (EmbeddedValueResolver) resolver;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
3 AbstractAutowireCapableBeanFactory#initializeBean
initializeBean 是初始化 Bean, 在创建 Bean 实例 createInstance(); 和 填充 bean 实例 populateBean(); 两个大的生命周期之后。 初始化 Bean 进行的第一步操作是执行 Aware 回调方法。该方法会给实现了 Aware 接口的对象注入相应的属性。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 执行 Aware 回调方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行 ApplicationContext 类型的 Aware 回调接口
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
4 AbstractAutowireCapableBeanFactory#invokeAwareMethods
执行 Aware 回调方法,执行顺序为:BeanName --> BeanClassLoader --> BeanFactory。
private void invokeAwareMethods(final String beanName, final 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);
}
}
}
5 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
在初始化 Bean 前运行 BeanPostProcessors。 postProcessBeforeInitialization 执行初始化前的扩展方法
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历所有的 BeanPostProcessors
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行 postProcessBeforeInitialization 回调方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
6 ApplicationContextAwareProcessor#postProcessBeforeInitialization
postProcessBeforeInitialization 该方法当前分析的 Aware 接口处于 ApplicationContextAwareProcessor 实现类中,所以,我们的 beanFactory 也需要为 ApplicationContext 类型才可以。
@Override
@Nullable
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 {
// 执行 Aware 接口列表
invokeAwareInterfaces(bean);
}
return bean;
}
7 ApplicationContextAwareProcessor#invokeAwareInterfaces
执行 ApplicationContext 类型的 Aware 接口回调方法 属性注入顺序即下面的添加顺序
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);
}
}
8 Aware 接口回调注入属性示例
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ClassName BeforeInstantiationBeanLifeCycleDemo
* @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
* @Author WQ
* @Date 2022/8/11 18:05
* @Version 1.0
*/
public class InstantiationBeanLifeCycleDemo {
public static void main(String[] args) {
executeBeanFactory();
executeApplicationContext();
}
private static void executeApplicationContext() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
applicationContext.setConfigLocations(locations);
applicationContext.refresh();
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = applicationContext.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
applicationContext.close();
}
private static void executeBeanFactory() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
reader.loadBeanDefinitions(locations);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}
}
Chapter 10 Spring Bean 初始化前阶段
1 概述
在前面的章节中 Bean 创建已完成如下步骤
- Bean 实例化
- Bean 属性赋值
- Bean Aware 接口回调
接下来为方法回调
- BeanPostProcessor#postProcessBeforeInitialization
2 applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 返回 null,则返回原始对象
if (current == null) {
return result;
}
// 否则替换为当前对象
result = current;
}
// 返回对象
return result;
}
3 SpringLifeCycleBeanPostProcessor 添加 BeanPostProcessors
postProcessBeforeInitialization 初始化前阶段回调
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.ChildUser;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.util.ObjectUtils;
/**
* @ClassName ChildUserInstantiationAwareBeanPostProcessor
* @Description TODO
* @Author WQ
* @Date 2022/8/15 15:57
* @Version 1.0
*/
public class SpringLifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
ChildUser childUser = new ChildUser();
childUser.setAge(22);
return childUser;
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
// if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
// User user = (User) bean;
// user.setId(815L);
// user.setName("小幸运");
// return false;
// }
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
final MutablePropertyValues propertyValues;
if (pvs instanceof MutablePropertyValues) {
propertyValues = (MutablePropertyValues) pvs;
} else {
propertyValues = new MutablePropertyValues();
}
propertyValues.add("number", "1111");
propertyValues.removePropertyValue("description");
propertyValues.addPropertyValue("description", "this is a description V2");
return propertyValues;
}
return null;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals(beanName, "user") && bean.getClass().equals(User.class)) {
return null;
}
return bean;
}
}
4 postProcessBeforeInitialization 使用示例
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ClassName BeanInitializationDemo
* @Description Bean 初始化生命周期示例
* @Author WQ
* @Date 2022/8/15 17:47
* @Version 1.0
*/
public class BeanInitializationLifeCycleDemo {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
applicationContext.setConfigLocations(locations);
applicationContext.refresh();
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = applicationContext.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
applicationContext.close();
}
}
Chapter 11 Spring Bean 初始化阶段
1 概述
Bean 初始化(Initialization)
- @PostConstruct 标注方法
- 实现 InitializingBean 接口的 afterPropertiesSet() 方法
- 自定义初始化方法
2 @PostConstruct 注解解析
@PostConstruct 需要注解驱动,PostConstruct 的 注入是在 以下代码段中,所以 PostConstruct 注解要生效,需要beanFactory 具有CommonAnnotationBeanPostProcessor 这个 BeanPostProcessor 的能力。
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
通过 @PostConstruct 添加 Bean 的初始化能力 示例
如果 beanFactory 不具有 CommonAnnotationBeanPostProcessor 的能力,可以调用如下 API 加入
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
UserHolder 中通过 @PostConstruct 添加初始化方法
public class UserHolder {
@PostConstruct
public void initPostConstruct() {
this.description = "this is a description V3";
System.out.println("initPostConstruct() : this.description" + this.description);
}
}
3 InitializingBean 接口的 afterPropertiesSet()方法分析
需要初始化的类需要实现 InitializingBean 并重写 afterPropertiesSet 方法,可以在该方法中对对象的属性值做修改,完成初始化操作。
public class UserHolder implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception {
this.description = "this is a description V4";
System.out.println("afterPropertiesSet() : this.description" + this.description);
}
}
4 自定义初始化方法
自定义初始化方法需要我们在需要初始化的 Bean 对象内部添加初始化方法
public void init () {
this.description = "this is a description V5";
System.out.println("init() : this.description" + this.description);
}
并到 XML 中添加相应初始化方法配置,配置如下
<?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">
<bean id="userHolder" class="com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder" autowire="constructor" init-method="init" >
<property name="description" value="this is a description V1" />
</bean>
<bean class="com.geekbang.thinking.in.spring.bean.lifecycle.SpringLifeCycleBeanPostProcessor"/>
</beans>
5 完整示例-需要初始化的 Bean UserHolder
package com.geekbang.thinking.in.spring.bean.lifecycle.domain;
import com.geekbang.spring.ioc.container.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringValueResolver;
import javax.annotation.PostConstruct;
/**
* @ClassName UserHolder
* @Description TODO
* @Author WQ
* @Date 2022/8/12 14:46
* @Version 1.0
*/
public class UserHolder implements InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware {
private User user;
private Integer number;
private String description;
private String beanName;
private ClassLoader classLoader;
private BeanFactory beanFactory;
private EmbeddedValueResolver resolver;
private Environment environment;
private ResourceLoader resourceLoader;
public UserHolder(User user) {
this.user = user;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "UserHolder{" +
"user=" + user +
", number=" + number +
", description='" + description + '\'' +
", beanName='" + beanName + '\'' +
", classLoader=" + classLoader +
", beanFactory=" + beanFactory +
", resolver=" + resolver +
", environment=" + environment +
", resourceLoader=" + resourceLoader +
'}';
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.resolver = (EmbeddedValueResolver) resolver;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@PostConstruct
public void initPostConstruct() {
this.description = "this is a description V3";
System.out.println("initPostConstruct() : this.description" + this.description);
}
@Override
public void afterPropertiesSet() throws Exception {
this.description = "this is a description V4";
System.out.println("afterPropertiesSet() : this.description" + this.description);
}
public void init() {
this.description = "this is a description V5";
System.out.println("init() : this.description" + this.description);
}
}
6 完整示例:XML配置
<?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">
<bean id="userHolder" class="com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder" autowire="constructor" init-method="init" >
<property name="description" value="this is a description V1" />
</bean>
<bean class="com.geekbang.thinking.in.spring.bean.lifecycle.SpringLifeCycleBeanPostProcessor"/>
</beans>
7 完整示例:获取对象,走初始化流程
package com.geekbang.thinking.in.spring.bean.lifecycle;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ClassName BeanInitializationDemo
* @Description Bean 初始化生命周期示例
* @Author WQ
* @Date 2022/8/15 17:47
* @Version 1.0
*/
public class BeanInitializationLifeCycleDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(locations);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}
}
8 源码分析一:@PostConstruct
在初始化 bean 的方法中执行了初始化回调方法,在初始化前阶段的 BeanPostProcessors 回调中已经执行了 @PostConstruct 初始化方法。 代码分析如下:
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
该方法在初始化之前运用所有的 BeanPostProcessors
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历所有的 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行 postProcessBeforeInitialization 方法
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
由于 @PostConstruct 在 CommonAnnotationBeanPostProcessor 中,并且该类继承了 InitDestroyAnnotationBeanPostProcessor 类,CommonAnnotationBeanPostProcessor 中没有重写 postProcessBeforeInitialization 方法,所以,直接看 InitDestroyAnnotationBeanPostProcessor 中的 postProcessBeforeInitialization 方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 寻找生命周期元信息
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;
}
这里我们在回顾一下 findLifecycleMetadata 寻找生命周期元信息的方法,该方法主要作用为构建缓存
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction...
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
// 构建生命周期元信息
metadata = buildLifecycleMetadata(clazz);
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
buildLifecycleMetadata 是从当前类开始找,递归查父类,找寻标注了 @PostConstruct 注解的方法
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
List<LifecycleElement> initMethods = new ArrayList<>();
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);
}
}
});
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));
}
回顾了寻找生命周期元信息以后,继续执行初始化方法 invokeInitMethods
public void invokeInitMethods(Object target, String beanName) throws Throwable {
Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
Collection<LifecycleElement> initMethodsToIterate =
(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
if (!initMethodsToIterate.isEmpty()) {
for (LifecycleElement element : initMethodsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
}
// 调用反射执行 @PostConstruct 标注的方法
element.invoke(target);
}
}
}
9 源码分析二: InitializingBean 接口与自定义初始化方法
在 initializeBean 方法中会去执行
invokeInitMethods(beanName, wrappedBean, mbd);
invokeInitMethods 做了两件事情:
- 执行的初始化方法为实现了 InitializingBean 接口的方法。
- 执行用户自定义的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判断是否为 InitializingBean 实例
boolean isInitializingBean = (bean instanceof InitializingBean);
// 判断是否为 InitializingBean 实例并且重写 afterPropertiesSet 方法
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 {
// 执行初始化方法 afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 从 RootBeanDefinition 上获取初始化方法
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 执行用户自定义的初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
10 源码分析三:三个初始化方法的执行顺序
在初始化方法中, @PostConstruct 注解标注的初始化方法在初始化执行运行 BeanPostProcessor 就已经执行,而 invokeInitMethods 方法中先执行实现了 InitializingBean 接口中的初始化方法,再执行用户自定义的初始化方法。 最终的结论为: @PostConstruct --> 实现 InitializingBean 接口的初始化方法 --> 用户自定义的初始化方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Chapter 12 Spring Bean 初始化后阶段
1 概述
方法回调
- BeanPostProcessor#postProcessAfterInitialization
初始化后阶段回调, 该回调可以再次修改 Bean 的属性值。
实现示例: 需要实现 BeanPostProcessor 并且重写 postProcessAfterInitialization 接口。
public class SpringLifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
ChildUser childUser = new ChildUser();
childUser.setAge(22);
return childUser;
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
// if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
// User user = (User) bean;
// user.setId(815L);
// user.setName("小幸运");
// return false;
// }
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
final MutablePropertyValues propertyValues;
if (pvs instanceof MutablePropertyValues) {
propertyValues = (MutablePropertyValues) pvs;
} else {
propertyValues = new MutablePropertyValues();
}
propertyValues.add("number", "1111");
propertyValues.removePropertyValue("description");
propertyValues.addPropertyValue("description", "this is a description V2");
return propertyValues;
}
return null;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals(beanName, "user") && bean.getClass().equals(User.class)) {
return null;
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals(beanName, "userHolder") && bean.getClass().equals(UserHolder.class)) {
UserHolder userHolder = (UserHolder) bean;
userHolder.setDescription("this is a description V6");
}
return null;
}
}
Bean 初始化后阶段生命周期示例
public class BeanInitializationLifeCycleDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
// 添加 BeanPostProcessor 重写 postProcessAfterInitialization 方法
beanFactory.addBeanPostProcessor(new SpringLifeCycleBeanPostProcessor());
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(locations);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
System.out.println(superUser);
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}
}
2 源码分析
AbstractAutowireCapableBeanFactory#initializeBean 的最后一个阶段为 初始化后阶段回调,调用了 applyBeanPostProcessorsAfterInitialization 方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历所有 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行初始化完成后阶段回调方法
Object current = processor.postProcessAfterInitialization(result, beanName);
// 如果返回的为 null, 则返回原来的对象
if (current == null) {
return result;
}
// 否则替换为当前对象
result = current;
}
return result;
}
Chapter 13 Spring Bean 初始化完成阶段
1 概述
方法回调
- Spring 4.1 +:SmartInitializingSingleton#afterSingletonsInstantiated
在 Spring Bean 的生命周期中,在 ApplicationContext 启动容器的时候,会在 Spring Bean 初始化完成以后才会调用该方法。 特点:
- afterSingletonsInstantiated 该方法需要显示调用,在 Spring 环境中,该方法的调用表明 Bean 已经初始化完毕,可以安全使用。
- preInstantiateSingletons 是 beanFactory 提供的一个方法,在 Bean 初始化完成以后调用。该方法中会去调用 Bean 的 afterSingletonsInstantiated 方法
什么是未初始化完毕呢? 比如在 BeanPostProcessors 还没执行完毕的时候,就进行了属性的更改或者返回代理对象,导致后续的流程不能正常执行。
2 源码分析
源码位置:AbstractApplicationContext#refresh 在 Spring 容器启动的过程中,会去调用 finishBeanFactoryInitialization 方法,在该方法前,所有 bean 的初始化工作都已经完成。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
3 DefaultListableBeanFactory#preInstantiateSingletons 分析
调用 getBean(beanName); 方法,后面会走 createBean 的流程,也会将 Spring Bean 的生命周期走一遍,这样所有的非延迟加载的 Bean 都会完成初始化,smartSingleton.afterSingletonsInstantiated(); 在执行的时候,Bean 已经初始化完毕了
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取 BeanFactory 中的所有 beanNames
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 遍历 beanName
for (String beanName : beanNames) {
// 根据 beanName 获取 RootBeanDefinition, 该 RootBeanDefinition 已经是触发 Merge 操作后的结果
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 该 RootBeanDefinition 不是抽象类 && 是单例模式 && 不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是否为工厂 Bean
if (isFactoryBean(beanName)) {
// 获取 bean 对象
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 如果 bean 是工厂 bean
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
// 是否需要立即初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
// 获取单例对象
Object singletonInstance = getSingleton(beanName);
// 如果对象实现了 SmartInitializingSingleton 接口
if (singletonInstance instanceof SmartInitializingSingleton) {
// 强制转换为 SmartInitializingSingleton 类型
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
// 触发单例 bean 实例化完成后的回调
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
Chapter 14 Spring Bean 销毁前阶段
1 概述
方法回调
- DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
2 源码分析
beanFactory#destroyBean
@Override
public void destroyBean(String beanName, Object beanInstance) {
destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
}
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
}
调用 DisposableBeanAdapter 的 destroy 方法,接下来重点分析 destroy 方法。
@Override
public void destroy() {
// 如果 beanPostProcessors 不为空
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
// 找出实现了 DestructionAwareBeanPostProcessor 接口的 bean,并调用 postProcessBeforeDestruction 方法
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 如果是个 DisposableBean
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
// 调用 DisposableBean#destroy 方法
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
// 执行用户自定义的销毁方法 (该方法采用反射去调用销毁方法)
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
// 如果配置文件中配置了 destroy 方法
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
Chapter 15 Spring Bean 销毁阶段
1 概述
Bean 销毁(Destroy)
- @PreDestroy 标注方法
- 实现 DisposableBean 接口的 destroy() 方法
- 自定义销毁方法