前言
Spring把一个个类包装成BeanDefinition之后,会经过一系列的BeanFactoryPostProcessor(Spring内置的或者程序员扩展的)的洗礼,这些在我之前的文章有详细讲述过,在这之后,新的风暴就要来临了,BeanDefinition会经历一个个BeanPostProcessor的摧残,成为真正的对象,这个过程就是著名的bean生命周期过程
脉络
我们先从整体的视角看bean的生命周期,bean的生命周期大致分为三个阶段
- 实例化
- 实例化前:开发者可以在这里做适当扩展,决定某个对象是否要走Spring实例化的流程
- 实例化:Spring在此处会通过反射正式创建一个对象,创建对象涉及到构造器推断,代码非常复杂
- 实例化后:跟我们平时开发是很类似的,new完对象后就要开始赋值了,开发者可以在这里做适当扩展,决定某个对象是否要走下面的Spring赋值流程
- 属性赋值
- new完对象后要开始赋值,世上没有后悔药,Spring有,如果对bean对象值的设置不满意,可以在这里进行修改
- 初始化阶段
- 初始化前,这里也可以进行赋值
- 初始化后,大名鼎鼎的AOP代理是在这里进行,我们new完一个对象后,想要对这个对象进行增强,拥有超级赛亚人的能力,就可以在这里改造
生命周期
实例化阶段
实例化前
我们先看一段代码,感受一下这个扩展点的作用
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("user") && beanClass.equals(User.class)) {
// 直接返回对象
return new User();
}
return null;
}
}
复制代码
public class Test {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加一个BeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 注册一个beanDefinition
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("id", 1L);
beanDefinitionBuilder.addPropertyValue("name", "crazy");
beanDefinitionBuilder.addPropertyValue("age", 22);
beanDefinitionBuilder.addPropertyValue("description", "V1");
beanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
Object user = beanFactory.getBean("user");
System.out.println(user);
}
}
复制代码
可以看到,因为不走bean的生命周期过程,所以类的属性都没有值
public class Test {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 不添加BeanPostProcessor
// beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 注册一个beanDefinition
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("id", 1L);
beanDefinitionBuilder.addPropertyValue("name", "crazy");
beanDefinitionBuilder.addPropertyValue("age", 22);
beanDefinitionBuilder.addPropertyValue("description", "V1");
beanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
Object user = beanFactory.getBean("user");
System.out.println(user);
}
}
复制代码
可以看到,不添加BeanPostProcessor,bean不返回null,就会走bean的生命周期了
看看源码是怎么写的
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
.......
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 注意这个判断,如果bean不为null,就不会走下面bean的生命周期流程
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
.....
}
复制代码
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 此处会循环迭代每个InstantiationAwareBeanPostProcessor
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
复制代码
实例化
我们都知道,spring是使用反射的方式来创建一个对象的,既然是使用反射的方式,就需要一个构造器,假设有这样一个场景,一个类的注入方式是构造器注入且有超过三个构造器,spring怎么知道使用哪个构造器来实例化一个对象呢?如果是你,你会怎么做呢?我们先看看示例代码,感受一下这个埋点的作用
// 实现BeanFactoryPostProcessor,修改beanDefinition,将AccountController改为构造器注入
@Component
public class ConstructorBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition accountController = (GenericBeanDefinition) beanFactory.getBeanDefinition("accountController");
accountController.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
}
}
复制代码
// AccountController有多个构造器
@Controller
public class AccountController {
private AccountService accountService;
private UserService userService;
public AccountController() {
System.out.println("none");
}
public AccountController(AccountService accountService) {
System.out.println("accountService");
}
public AccountController(UserService userService) {
System.out.println("userService");
}
public AccountController(AccountService accountService, UserService userService) {
System.out.println("accountService, userService");
}
}
复制代码
@Service
public class AccountService {
}
复制代码
@Service
public class UserService {
}
复制代码
public class ConstructorTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(Config.class);
applicationContext.refresh();
applicationContext.getBean("accountController");
applicationContext.close();
}
}
复制代码
因为场景较多,不一一举例,在推断构造器的过程中,spring有两次推断的过程,第一次推断的过程AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors方法中,有以下几种场景
- 该类没有提供构造方法,该方法返回null
- 该类提供了默认的构造方法且只有一个,返回该构造器
- 该类提供了多个构造方法,但其中有一个构造方法使用@Autowired(required = true)注解修饰,返回该构造器
- 该类提供了多个构造方法,但是没有构造器使用@Autowired注解修饰,返回null
- 该类提供了多个构造方法,有构造器使用@Autowired(required = false)注解修饰,返回使用@Autowired(required = false)注解修饰的构造器+默认无参构造器
如果自动装配模式是构造器注入的话,就需要进行二次推断
- 如果第一次推断已经选定了一个构造器,就会使用这个构造器进行实例化
- 如果第一次推断没有选定构造器,返回null的话,就会获取该类中所有构造器进行二次推断,再进行实例化
- 如果第一次推断没有选定构造器,返回了多个构造器的话,就会在多个构造器中选择一个构造器实例化
二次推断主要是比较构造器参数的匹配程度
看看超级复杂的源代码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 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());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果factoryMethodName不为空,则使用factoryMethodName的方式实例化,主要在@Bean的这种场景
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// resolved相当于一个标记,当重复创建bean对象时,由于之前已经推断过bean的构造方法了,就不需要重复推断了
// resolved表示是不是已经推断过
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// resolvedConstructorOrFactoryMethod不为null,表示已经找到了创建对象的方式,这个方式有可能是通过构造器的方式,也有可能是通过
// factoryMethod的方式
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 标记位设置为true
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// 这里是重点,调用BeanPostProcessor推断构造方法
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);
}
// 使用默认无参构造器进行实例化
return instantiateBean(beanName, mbd);
}
复制代码
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// 这个方法的第一部分是@Lookup相关的逻辑,现在较少使用,我们不看
...
// 先从缓存中获取已经被推断完成的类和该类被推断出来的构造方法集合,如果缓存中有,就不需要重复推断
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
synchronized (this.candidateConstructorsCache) {
// 非常熟悉的方式,一个double check
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
// 获取当前类所有的构造器
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
// candidates,用来存储合格的构造器,加入合格的构造器
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
// 下面整个推断的思路是这样的,如果一个类有多个构造器,这么多个构造器中,如果有使用@Autowired(required = true)修饰的构造器
// 那么就使用这个构造器实例化,如果没有,则使用默认构造器(即无参构造器)
// 实例化使用的构造器
Constructor<?> requiredConstructor = null;
// 默认构造器,用来存储无参构造器
Constructor<?> defaultConstructor = null;
// kotlin相关的代码,本人水平有限,看不懂
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
for (Constructor<?> candidate : rawCandidates) {
// 判断该构造器是不是合成的构造器
if (!candidate.isSynthetic()) {
// 非合成的构造器加1,做一个记录
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 获取构造器上的注解,看看有没有被@Autowired修饰
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
// 如果该构造器上没有@Autowired注解
if (ann == null) {
// 有可能是因为这个类被cglib代理了,所以要获取该类的父类,因为cglib是通过生成子类的方式进行代理
Class<?> userClass = ClassUtils.getUserClass(beanClass);
// 如果两个类不相同,说明此类确实是cglib代理了
if (userClass != beanClass) {
try {
// 再次获取该构造器
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
// 在此看看构造器上是不是有@Autowired注解
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 如果构造器上有@Autowired注解
if (ann != null) {
// 这里会直接报错,说明之前已经找到了@Autowired(required = true)的构造器,现在又找到了一个,spring不知道要用哪个构造器进行
// 实例化,只能报错了
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// @Autowired(required = true),获取@Autowired中required属性是true还是false
boolean required = determineRequiredStatus(ann);
// 如果是true,直接将这个构造器赋值给requiredConstructor,之后会使用这个构造器实例化
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
// 构造器参数为空,说明是无参构造器,赋值为默认构造器
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 如果候选构造器不为空但是requiredConstructor为空,则获取
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 如果该类只有一个构造器,则使用这个构造器进行实例化
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// primaryConstructor是与kotlin有关的判断,本人水平有限,就不看了
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
// 不满足以上的条件,就是空数组了
candidateConstructors = new Constructor<?>[0];
}
// 将推断过的类与该类的构造器放入缓存中
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 返回候选的构造器
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
复制代码
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 最终实例化使用的构造器
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 构造器实例化最终使用的参数
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 看下面的代码之前,需要先理解一个东西,构造器中的某些参数需要经过解析才能转变为真正的参数,什么意思?
// <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
// 比如这个配置,value是一个字符串,但是这个属性应该是一个类,所以这个spring需要先解析这个value,将它变成一个类,才能进行赋值
// resolvedConstructorOrFactoryMethod:这个属性上面有讲过,表示创建对象的方式,如果已经推断出来创建对象的方式,
// 就可以直接获取
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果实例化使用的构造器不为空,并且需要的参数也解析好了
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// argsToUse保存了已经解析好的参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// argsToUse为空,表示参数还没有解析好,argsToResolve保存了未解析的参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// argsToResolve不为空,表示参数还未解析好
if (argsToResolve != null) {
// 将参数进行解析,并且赋值给argsToUse
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// constructorToUse或者argsToUse为空,表示还未进行构造器的二次推断
if (constructorToUse == null || argsToUse == null) {
// 将传入的构造器赋值给candidates
Constructor<?>[] candidates = chosenCtors;
// 如果传入的构造器为空,则通过反射的方式去获取类的构造器
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
// isNonPublicAccessAllowed这个属性的意思是是否允许访问非公开方法、构造函数
// 如果允许,则获取所有构造器(包括非公有的)
// 否则,则获取公有的
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);
}
}
// 如果候选构造器只有一个并且这个构造器没有参数,这样的构造器只有一个,就是默认无参构造器
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;
}
}
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
// 方法的参数数量的最小值
// 匹配的方法的入参数量要多于它
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 从beanDefinition解析出方法的参数个数作为最小值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 对构造器进行排序,public方法优先,参数个数多的优先
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 {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
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);
}
// 判断解析构造函数的时候是以宽松模式还是严格模式,默认为true
// 严格模式:解析构造函数时,必须所有的都需要匹配,否则抛出异常
// 宽松模式:使用具有"最接近的模式"进行匹配
// typeDiffWeight:类型差异权重
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// typeDiffWeight < minTypeDiffWeight 表示是截止目前为止最符合的构造器
if (typeDiffWeight < minTypeDiffWeight) {
// 替换参数
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
// 如果类型差异权重相等,说明构造器极为相似,spring分辨不出来哪个比较合适,就放进ambiguousConstructors集合中
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);
}
// 将解析出来的构造器放进beanDefinition
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
// 实例化一个对象
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
复制代码
实例化后
Spring把实例化后的代码放在填充属性的方法中,因为这个埋点可以决定是否进行Spring的填充属性,下面的示例代码与填充属性中的埋点一起展示
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;
}
}
// 这个埋点下面有例子
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 我们可以在这个埋点中做自定义的属性注入,或者return false,让某个类不走spring属性注入的流程
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
......
}
复制代码
属性赋值阶段
属性正式赋值前可以修改属性,之所以有两个埋点,是因为Spring有不同的版本,不同版本的方法不同,Spring的源码中已经将旧方法废弃了
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation:属性正式注入到bean之前,如需修改可以在这里修改(旧)
InstantiationAwareBeanPostProcessor#postProcessProperties:属性正式注入到bean之前,如需修改可以在这里修改(新)
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
.......
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);
// byName的方式注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// byType的方式注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 这里又是两个埋点,在spring属性正式注入到bean之前,我们可以在这里修改属性的值
// 两个埋点的作用是一样的,都是修改属性,一个是spring旧版本的埋点,一个是spring新版本的埋点,为了兼容,两个都存在了
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 新埋点
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) {
// 将pvs中的值注入到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
复制代码
看看示例代码,感受一下这几个埋点的作用
@Data
public class User {
private long id;
private String name;
private int age;
private String description;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", description='" + description + '\'' +
'}';
}
}
复制代码
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
((User) bean).setDescription("V2");
System.out.println("V2");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
final MutablePropertyValues propertyValues;
if (pvs instanceof MutablePropertyValues) {
propertyValues = (MutablePropertyValues) pvs;
} else {
propertyValues = new MutablePropertyValues();
}
if (pvs.contains("description")) {
propertyValues.removePropertyValue("description");
propertyValues.addPropertyValue("description", "V3");
System.out.println("V3");
}
}
return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
}
// 这个扩展点spring是不建议使用的
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
final MutablePropertyValues propertyValues;
if (pvs instanceof MutablePropertyValues) {
propertyValues = (MutablePropertyValues) pvs;
} else {
propertyValues = new MutablePropertyValues();
}
if (pvs.contains("description")) {
propertyValues.removePropertyValue("description");
propertyValues.addPropertyValue("description", "V4");
System.out.println("V4");
}
}
return InstantiationAwareBeanPostProcessor.super.postProcessPropertyValues(pvs, pds, bean, beanName);
}
}
复制代码
public class Test {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加一个BeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 注册一个beanDefinition
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("id", 1L);
beanDefinitionBuilder.addPropertyValue("name", "crazy");
beanDefinitionBuilder.addPropertyValue("age", 22);
beanDefinitionBuilder.addPropertyValue("description", "V1");
beanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
Object user = beanFactory.getBean("user");
System.out.println(user);
}
}
复制代码
如下图,我们可以版本号看到执行的顺序
初始化阶段
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 这代码没看懂,貌似是安全方面的检查
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 如果bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,注入对应属性
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 如果bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,注入对应属性
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// bean初始化前的埋点,这里有一个比较重要的实现类ApplicationContextAwareProcessor,会注入我们常用的ApplicationContextAware、
// EnvironmentAware 等属性,代码很好懂,有兴趣的同学可以看一下
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 这里有afterPropertiesSet和init-method两个方法的扩展
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// bean初始化后的埋点,大名鼎鼎的AOP就是在这里做扩展
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
// 以下的代码都很浅显易懂,如果bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口
// 对这个bean注入对应属性
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
复制代码