BeanPostProcessor 和 InstantiationAwareBeanPostProcessor
BeanPostProcessor
bean 后置处理器,bean 创建对象初始化前后进行拦截工作的,初始化前后,可以理解为。 给 bean 设置了 initMethod 属性。 一个是在 initMethod 之前执行。 一个是在 initMethod 方法之后执行。InstatntiationAwareBeanPostProcessor
:实际上本身也是继承了 BeanPostProcessor 接口的。 主要是扩展了实例化之前的回调。以及在实例化之后但设置了显式属性或者发生自动装配之前的回调。
BeanPostProcessor.java
public interface BeanPostProcessor {
/**
* 用于在Bean初始化方法执行之前执行。
* 当 Bean 设置 initMethod 初始化方法的时候。 会在 initMethod 方法之前执行。 不设置也会执行。 只是一个执行顺序
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* 用于 Bean 初始化方法执行之后执行
* 当 Bean 设置 initMethod 初始化方法的时候, 会在 initMethod 方法之后执行。 不设置也会执行。
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InstantiationAwareBeanPostProcessor.java
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 用于在 Bean 实例化之前调用。类似于 new Object() 之前调用。
* 如果该方法返回的值不为空的话,则直接将该对象作为创建的 bean 返回给 spring 容器
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 用于在 Bean 实例化之后调用。类似于 new Object() 之后调用。
* 如果该方法返回 true 的话。继续执行下一个 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法
* 直到执行完毕都没有返回 false 的话。继续给之前创建的对象设置属性。
* 如果又一个 postProcessAfterInstantiation 返回了 false. 都不会继续执行下去。直接跳过初始化设置属性值的步骤
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* PropertyValues 该类是用于描述当前 bean 对象的属性名 -> 属性值
* 如果该方法返回的为空,则继续使用原来的 PropertyValues 对象。
* 如果返回的不为空,则替换掉原有的 PropertyValues 对象。
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* 该方法和postProcessProperties的作用是一致的。 不过已经标记为废除的状态。不推荐使用。不过多解释了
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
创建 Bean 的过程
BeanFactory Bean 工厂类的默认唯一实现为 DefaultListableFactory。 当我们通过 Bean 工厂创建一个Bean的时候。如果在缓存中不存在这个 Bean 的时候,工厂类会选择创建一个 Bean 。 主要创建方法就 AbstractAutowireCapableBeanFactory#createBean
.
代码片段
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
AbstractAutowireCapableBeanFactory#createBean
方法传入三个参数, 一个是 bean 的名称, 一个是 BeanDefinition 对象 - 以下使用 mdb简称
。
以下只说明 BeanPostProcessor 和 InstantiationAwareBeanPostProcessor 中的执行顺序。 方法中会解析 mdb 中的 class 属性。 beanClass 属性刚开始是 String 的类型。会通过反射将 beanClass 属性加载为 Class 对象。 该 Class 对象会作为 InstantiationAwareBeanPostProcessor 中 postProcessBeforeInstantiation 方法的第一个参数。 以下的代码片段省略了很多不必要的信息
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 解析 BeanDefinition 中的 beanClass 属性,得到 Class 对象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
// 将解析的Class 对象
mbdToUse.setBeanClass(resolvedClass);
}
// 执行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 如果返回的 bean 不为空 ,则直接将该方法返回的 bean 直接 return
if (bean != null) {
return bean;
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
具体看一下 resolveBeforeInstantiation 中执行了什么方法, 可以看到还是先从 mdb 中获取到 Class 的类对象。然后调用 applyBeanPostProcessorsBeforeInstantiation 方法, 该方法中自然是获取到所有的 InstantiationAwareBeanPostProcessor 对象,然后循环调用 postProcessBeforeInstantiation 方法 . 调用完之后 如果 不为空的话。还会调用一遍 applyBeanPostProcessorsAfterInitialization 。 该方法自然是获取到所有的BeanPostProcessor然后调用 postProcessAfterInitialization 方法。 此方法自然是当我的 bean 全部初始化完毕之后的最后调用的方法,在这里调用是为了和之后的正常加载的 bean 保持一致性,因为在这里处理的 bean 都是已经处理完毕的。直接返回
@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) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
看一下 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
的代码片段, 获取所有的 InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation 方法
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
代码片段,获取所有的 BeanPostProcessor 调用 postProcessAfterInitialization 方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
继续回到刚刚的 createBean
方法。可以看到 如果 resolveBeforeInstantiation 方法返回不为空的话,则直接返回该方法创建的 bean 对象
查看一下 doCreateBean 方法,这边是真正的创建 Bean 的过程 .
先介绍一下 BeanWrapper ;
BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性
AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
// 判断是否为单例 bean
if (mbd.isSingleton()) {
// 从未完成的 bean 缓存的中移除当前需要创建的 bean
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 判断如果为 null 的话, 不是之前创建过的未完成的 bean 则需要创建一个 beanInstance
if (instanceWrapper == null) {
// 在这里 createBeanInstance 方法 会通过反射的方式来创建一个 当前 mbd 所定义的一个类对象包装在 BeanWrapper 实例中
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取对应的 bean 对象实例
final Object bean = instanceWrapper.getWrappedInstance();
// 获取 beanType 的 Class 对象
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
// 如果不是 NullBean.class 的话,则会将其缓存起来
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
// 这边会判断是否已经合并应用过。 就是用于判断是否调用过这个 mergedBeanDefinitionPostProcessor
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);
}
// 调用过就会设置为 true 防止重复调用
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 判断条件非别是 是否为 单例 bean, 是否允许循环依赖引用, 是否为单例并且创建中的 bean
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 {
// 对创建好的 bean 对象进行属性的初始化
populateBean(beanName, mbd, instanceWrapper);
// 对属性初始化完成的 bean 对象执行初始化方法回调
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) {
// 根据 beanName 获取早期 bean 的引用 。
// getBean 的第二个参数如果为 false 则只会查找到二级缓存。 如果为 true 则会去三级缓存中查找
// 当前查询的时候如果不为空。说明对象已经存在于二级缓存中了。
// 那么bean对象是什么时候将对象放入到二级缓存中的呢。 等下看代码就知道了
Object earlySingletonReference = getSingleton(beanName, false);
// 如果不为 null
if (earlySingletonReference != null) {
// 判断初始化完成之后的 exposedObject 和 bean 的引用地址是否发生变化
if (exposedObject == bean) {
// 如果一致说明并没有发生变化将缓存中的对象引用赋值给 exposedObject
exposedObject = earlySingletonReference;
}
// 如果不一致。 则说明在上面的初始化中可能使用了代理或者其他的原因导致对象地址发生变化
// allowRawInjectionDespiteWrapping 默认为 false , 是否允许早起暴露出去的 bean 和 当前 bean 的引用地址是否一致
// hasDependentBean 表示有哪些 bean 依赖于 beanName
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 获取有哪些 bean 依赖于 beanName
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 循环遍历判断 dependentBean是否已经被创建过了。 就是判断 dependentBean 是否已经被创建了
for (String dependentBean : dependentBeans) {
// 将已经穿件的 bean 添加到这个actualDependentBeans 集合中。 说明早期的 bean 已经被使用了。
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 到这里之后。说明早期的 bean 已经被使用过了。 而后面又将 exposedObject 做了修改。
// 本来原来的 bean 是 A。 A 已经在有些地方使用了。但是 A 后期创建完成之后 , 又通过 initializeBean 修改。 变成了 B。 这个时候就会抛出异常报错了
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 {
// 用于注册容器销毁时需要执行销毁逻辑的bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
一步一步来解析上面的步骤
AbstractAutowireCapableBeanFactory#createBeanInstance
就不详细说了,总的来说大概就是通过 beanName, BeanDefinition 来创建一个 BeanWrapper 的对象。 通过反射创建一个 bean 对象。 然后封装到 BeanWrapper 中。主要是看 BeanPostProcessor 的执行顺序。
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
该方法用于调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
方法,该方法可以通过对 Class 对象进行扫描。然后修改 BeanDefinition 对象的定义,从而达到对 bean 对象字段的注入和修改。该接口的实现类有很多。还都比较重要
上面这些。都是提供了 Spring 的一些注解的支持。 比如 @Value
和 @Autowried
. 还有 @Inject
具体的不详细说了哈。有空再写其他的笔记。
继续往下执行。
populateBean(beanName, mbd, instanceWrapper);
该方法适用于给创建的 bean 对象设置属性值。上面的 createBeanInstance
是用来创建 bean 的。 比如 User user = new User();
这一步的 populateBean
可以理解为 user.setUsername("Gao");
代码片段。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 判断是否为 InstantiationAwareBeanPostProcessor 的类对象
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 在给对象设置值之前调用。 如果调用 postProcessAfterInstantiation 方法的时候
// 但凡有一次返回的为 false , 就直接结束该方法 不继续执行。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 用于判断是否存在 InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
// 获取 PropertyValues 。
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 通过调用 InstantiationAwareBeanPostProcessor#postProcessProperties 的方法
// 此处可以通过修改 PropertyValues 的值来修改即将给 bean 对象赋值的属性值。
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// 返回如果等于 null 的话
if (pvsToUse == null) {
// 则继续执行
if (filteredPds == null) {
// 提取一组过滤的 PropertyDescritor
// PropertyDescritor 属性描述器、可以理解为用于描述当前类的字段,读写字段的方法都可以通过该类来直接调用
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 继续调用 InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues 方法。 不过当前方法已经被标记为废除。不推荐使用。
// 如果之前的 postProcessProperties 方法返回不为 null 的话。则该方法就没有调用的必要了。
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);
}
}
以上就是给 bean 对象初始化值的调用流程了。分别顺序执行了 postProcessAfterInstantiation
、postProcessProperties
和 postProcessPropertyValues
方法。
执行完对象初始化值的操作之后,开始执行对 bean 的回调函数了。比如设置的 initMethod ,实现 Aware 接口的回调。
exposedObject = initializeBean(beanName, exposedObject, mbd);
看看这个方法中具体做了些什么事情吧 。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
上面是我精简过的代码。看这些方法的名字,大概也能猜的出来。 首先是 invokeAwareMethods(beanName, bean);
。
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);
}
}
}
这个方法会判断当前bean是否实现了 Aware 接口。 并且是否实现了BeanNameAware, BeanClassLoaderAware, BeanFactory
. 如果实现了。则会调用各自的回调方法。执行对应的回调函数。
继续看 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
。
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 循环调用 BeanPostProcessor 的前置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 如果当前处理器返回 null 的话。则直接将原来的 Bean 返回出去。
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
// 如果不为 null, 则将返回修改过的 bean 进行赋值给原来的引用。继续处理
result = current;
}
return result;
}
可以看到开始调用 BeanPostProcessor #postProcessBeforeInitialization
方法。
继续执行 invokeInitMethods(beanName, wrappedBean, mbd);
代码稍微精简了一下。
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判断 bean 是否实现了 InitializingBean。
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
// 对bean转型,并执行 afterPropertiesSet()
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 通过获取在 BeanDefinition 中定义的 initMethod 方法名
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 通过反射调用 initMethod 方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
可以看到。invokeInitMethods
方法就是先调用实现了 InitializingBean 接口的bean的初始化方法。然后通过反射调用在 BeanDefinition 中定义的 initMethod 初始化方法 methodToInvoke.invoke(bean);
到这一步。bean 的初始化算是彻底完成了。然后就剩下后置处理器了。
调用 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
不用我说。也应该知道是调用 BeanPostProcessor 的 postProcessAfterInitialization 方法吧。还记的前面的有一个方法直接返回的 bean 对象。就不会继续执行了的那一步吗?哪个返回 bean 对象之后。也会执行所有的 postProcessAfterInitialization 后置处理器方法。保持一致
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
initializeBean
方法执行完毕之后。后面就是上面讲的判断这个方法返回的 bean. 引用地址是否发生变化,如果变化了、那么在这值钱有没有地方调用过。如果有则抛出异常之类的。
分析完毕之后。那么准备写 demo 测试一下吧。 创建项目的步骤省略。 引入依赖。直接引入 Spring 5.0 的依赖就好。
创建一个 Student 类
/**
* @Author: gssznb
*/
public class Student implements InitializingBean, BeanFactoryAware, BeanNameAware, BeanClassLoaderAware {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
'}';
}
/**
* 实现 InitializingBean 的初始化方法
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
incre("InitializingBean#afterPropertiesSet");
}
public void initMethod() {
incre("BeanDefinition#initMethod");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
incre(String.format("BeanFactoryAware#setBeanFactory, beanFactory : [ %s ]", beanFactory));
}
@Override
public void setBeanName(String name) {
incre(String.format("BeanNameAware#setBeanName: beanName : [ %s ]", name));
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
incre(String.format("BeanClassLoaderAware#setBeanClassLoader: beanClassLoader: [ %s ]", classLoader));
}
}
实现了 InitializingBean, BeanFactoryAware, BeanNameAware, BeanClassLoaderAware
四个接口。其实还可以更多。 比如 ApplicationContextAware 之类的。 就不写了。可以自己研究一下。
创建一个 BeanPostProcessor 和 InstantiationAwareBeanPostProcessor 的实现类
/**
* @Author: gssznb
*/
@Component
public class StudentBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
MainConfig.incre(String.format("BeanPostProcessor#postProcessBeforeInitialization -- " +
"bean : [ %s ], beanName : [ %s ]", bean, beanName));
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
MainConfig.incre(String.format("BeanPostProcessor#postProcessAfterInitialization -- " +
"bean : [ %s ], beanName : [ %s ]", bean, beanName));
return bean;
}
}
/**
* @Author: gssznb
*/
@Component
public class StudentInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
incre(String.format("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation" +
"-- beanClass: [ %s ], beanName : [ %s ]", beanClass, beanName));
return null;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
incre(String.format("InstantiationAwareBeanPostProcessor#postProcessBeforeInitialization"));
return bean;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
incre("InstantiationAwareBeanPostProcessor#postProcessProperties");
return null;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
incre("已标记废除 -- InstantiationAwareBeanPostProcessor#postProcessPropertyValues");
return pvs;
}
}
创建一个配置类 MainConfig
/**
* @Author: gssznb
*/
@Configuration
@ComponentScan(basePackages = {"org.geekbang.thinking.spring.ioc.bean.lifecyclenew3"})
public class MainConfig {
/**
* 作为计数器。
*/
public static Integer count = 0;
public static void incre(String position) {
count++;
System.out.println(String.format(position + " -- [ %d ]", MainConfig.count));
}
@Bean(initMethod = "initMethod")
public Student student() {
return new Student();
}
}
写测试方法
@Test
public void test1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Student student = context.getBean("student", Student.class);
System.out.println(student);
}
运行执行打印结果
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation-- beanClass: [ class org.geekbang.thinking.spring.ioc.bean.lifecyclenew3.MainConfig$$EnhancerBySpringCGLIB$$5ece0fcd ], beanName : [ mainConfig ] -- [ 1 ]
InstantiationAwareBeanPostProcessor#postProcessProperties -- [ 2 ]
已标记废除 -- InstantiationAwareBeanPostProcessor#postProcessPropertyValues -- [ 3 ]
BeanPostProcessor#postProcessBeforeInitialization -- bean : [ org.geekbang.thinking.spring.ioc.bean.lifecyclenew3.MainConfig$$EnhancerBySpringCGLIB$$5ece0fcd@1d119efb ], beanName : [ mainConfig ] -- [ 4 ]
InstantiationAwareBeanPostProcessor#postProcessBeforeInitialization -- [ 5 ]
BeanPostProcessor#postProcessAfterInitialization -- bean : [ org.geekbang.thinking.spring.ioc.bean.lifecyclenew3.MainConfig$$EnhancerBySpringCGLIB$$5ece0fcd@1d119efb ], beanName : [ mainConfig ] -- [ 6 ]
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation-- beanClass: [ class org.geekbang.thinking.spring.ioc.bean.lifecyclenew3.Student ], beanName : [ student ] -- [ 7 ]
InstantiationAwareBeanPostProcessor#postProcessProperties -- [ 8 ]
已标记废除 -- InstantiationAwareBeanPostProcessor#postProcessPropertyValues -- [ 9 ]
BeanNameAware#setBeanName: beanName : [ student ] -- [ 10 ]
BeanClassLoaderAware#setBeanClassLoader: beanClassLoader: [ sun.misc.Launcher$AppClassLoader@18b4aac2 ] -- [ 11 ]
BeanFactoryAware#setBeanFactory, beanFactory : [ org.springframework.beans.factory.support.DefaultListableBeanFactory@6a1aab78: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,mainConfig,studentBeanPostProcessor,studentInstantiationAwareBeanPostProcessor,student]; root of factory hierarchy ] -- [ 12 ]
BeanPostProcessor#postProcessBeforeInitialization -- bean : [ Student{username='null'} ], beanName : [ student ] -- [ 13 ]
InstantiationAwareBeanPostProcessor#postProcessBeforeInitialization -- [ 14 ]
InitializingBean#afterPropertiesSet -- [ 15 ]
BeanDefinition#initMethod -- [ 16 ]
BeanPostProcessor#postProcessAfterInitialization -- bean : [ Student{username='null'} ], beanName : [ student ] -- [ 17 ]
Student{username='null'}
执行顺序和我们之前分析的一致把。 哈哈 大概就这样子了。 后面有时间的时候再搞一些其他的东西