- BeanFactoryPostProcessor:是针对于beanFactory的扩展点,即spring会在beanFactory初始化之后,beanDefinition都已经loaded,但是bean还未创建前进行调用,可以修改,增加beanDefinition
- BeanPostProcessor:是针对bean的扩展点,即spring会在bean初始化前后 调用方法对bean进行处理
-
总结:以上两种都为Spring提供的后处理bean的接口,只是两者执行的时机不一样。BeanPostProcessor为实例化之后,BeanFactoryPostProcessor是实例化之前。
BeanFactoryPostProcessor:BeanFactory级别的处理,是针对整个Bean的工厂进行处理
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
此接口只提供了一个方法,方法参数为ConfigurableListableBeanFactory,下面看看这个类里面定义了哪些方法
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
void ignoreDependencyType(Class<?> type);
void ignoreDependencyInterface(Class<?> ifc);
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
Iterator<String> getBeanNamesIterator();
void clearMetadataCache();
void freezeConfiguration();
boolean isConfigurationFrozen();
void preInstantiateSingletons() throws BeansException;
}
其中有个方法名为getBeanDefinition的方法,我们可以根据此方法,找到我们定义bean的BeanDefinition对象。然后我们可以对定义的属性进行修改.
BeanDefinition里面的方法名字类似我们bean标签的属性,setBeanClassName对应bean标签中的class属性,所以当我们拿到BeanDefinition对象时,我们可以手动修改bean标签中所定义的属性值。
具体这个BeanDefinition是个什么对象,当我们在xml中定义了bean标签时,Spring会把这些bean标签解析成一个javabean,这个BeanDefinition就是bean标签对应的javabean。
所以当我们调用BeanFactoryPostProcess方法时,这时候bean还没有实例化,此时bean刚被解析成BeanDefinition对象。
Spring容器初始化bean大致过程 定义bean标签>将bean标签解析成BeanDefinition>调用构造方法实例化(IOC)>属性值得依赖注入(DI)
BeanPostProcessor:bean级别的处理,针对某个具体的bean进行处理
public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
接口提供了两个方法,分别是初始化前和初始化后执行方法,具体这个初始化方法指的是什么方法,类似我们在定义bean时,定义了init-method所指定的方法<bean id = "xxx" class = "xxx" init-method = "init()">
这两个方法分别在init方法前后执行,需要注意一点,我们定义一个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进行处理。
既然是默认全部处理,那么我们怎么确认我们需要处理的某个具体的bean呢?
可以看到方法中有两个参数。类型分别为Object和String,第一个参数是每个bean的实例,第二个参数是每个bean的name或者id属性的值。所以我们可以第二个参数,来确认我们将要处理的具体的bean。
这个的处理是发生在Spring容器的实例化和依赖注入之后。
网友评论