Spring面试系列---BeanFactoryPostProcessor和BeanPostProcessor的区别

BeanFactoryPostProcessor和BeanPostProcessor都是Spring中预留的扩展接口,单从两个接口的名称大概可以看出BeanFactoryPostProcessor是针对BeanFactory的扩展,而BeanPostProcessor是针对Bean的扩展。

先来看一下两个接口中的方法

BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

BeanPostProcessor

public interface BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

其中BeanPostProcessor中的方法应该比较熟悉了,就是所谓bean的前置处理器和bean的后置处理器,一般只要阅读过一些源码的应该都有遇到过这两个方法。

BeanFactoryPostProcessor是在bean实例化之前调用的,可以在容器启动时修改bean的定义。

ConfigurationClassPostProcessor这个类间接的实现了BeanFactoryPostProcessor的接口。
Spring面试系列---BeanFactoryPostProcessor和BeanPostProcessor的区别_第1张图片
重写方法。

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}

		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

这个方法会在bean的实例化开始之前就调用,动态完成对有@Bean注解的bean对象添加相关属性定义。

BeanPostProcessor接口中的两个方法则是在bean对象已经实例化完成后,初始化开始时调用到的,主要是完成初始化前后的一些方法的调用。

	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()) {
			//调用postProcessBeforeInitialization
			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()) {
			//调用applyBeanPostProcessorsAfterInitialization
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

InitDestroyAnnotationBeanPostProcessor这个类间接实现了BeanPostProcessor接口
Spring面试系列---BeanFactoryPostProcessor和BeanPostProcessor的区别_第2张图片
重写方法

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		//收集有@PostConstruct,@PreDestroy注解
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			//调用@PostConstruct注解的方法
			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;
	}

所以可以看出@PostConstruct,@PreDestroy底层是通过BeanPostProcessor的postProcessBeforeInitialization接口完成的。

至于postProcessAfterInitialization可以实现生成bean的代理,例如AbstractAutoProxyCreator的实现。

	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

总结
Spring面试系列---BeanFactoryPostProcessor和BeanPostProcessor的区别_第3张图片

你可能感兴趣的:(Spring,IOC,spring,java)