Spring的后处理器
目录
引言
BeanFactoryPostProcessor
注意
BeanPostProcessor
引言
Spring的后处理器是spring对外开发的重要扩展点,允许我们介入到Bean的整个实例化流程来,以达到动态注册BeanDefintion,动态修改BeanDefintion,以及动态修改Bean的作用。
Spring主要有两种后处理器:
-
BeanFactoryPostProcessor:Bean工厂后处理器,BeanDefintionMap填充完毕,Bean实例化之前执行;
-
BeanPostProcessor:Bean后处理器,一般在Bean实例化之后,填充单例池singletonObjects之前执行
BeanFactoryPostProcessor
BeanFactoryPostProcessor是一个接口规范,实现该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对BeanDefinition注册和修改的功能
完善Bean实例化图
package com.xfy.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyBeanFactorypostprocessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory BeanFactory) throws BeansException {
System.out.println("pPBF");
//修改某个BeanDifinition的全限定名,将某个Bean的类型改变
BeanDefinition userDao = BeanFactory.getBeanDefinition("userDao");
userDao.setBeanClassName("com.xfy.service.impl.UserServiceImpl");
//动态的去注册一个BeanDefinition
BeanDefinition BeanDefinition = new RootBeanDefinition();
BeanDefinition.setBeanClassName("com.xfy.dao.Impl.PersonDaoImpl");
DefaultListableBeanFactory DBeanFactory= (DefaultListableBeanFactory) BeanFactory;
DBeanFactory.registerBeanDefinition("personDao",BeanDefinition);
}
}
<bean class="com.xfy.processor.MyBeanFactorypostprocessor"></bean>
注意
Spring提供了一个BeanFactoryPostProcessor的子接口DBeanFactoryRegisterPostProcessor专门用于注册BeanDefintion操作 如下代码
package com.xfy.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyBeanFactorypostRegistryprocessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
RootBeanDefinition beanDefinition = new RootBeanDefinition("com.xfy.dao.Impl.PersonDaoImpl");
beanDefinitionRegistry.registerBeanDefinition("personDao",beanDefinition);
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
BeanPostProcessor
Bean被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程,例如:属性填充,初始化方法init的执行等,其中有一个对外进行扩展的点BeanPostProcessor。我们称为Bean后处理器,跟上面的Bean工厂后处理器相似,他也是一个接口,实现该接口并被容器管理的BeanPostProcessor,会在流程节点上被Spring自动调用
完善Bean实例化流程图
代码实现对Bean的属性赋值如下:
package com.xfy.processor;
import com.xfy.anno.MyComponent;
import com.xfy.dao.Impl.UserDaoImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@MyComponent("mbpp")
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof UserDaoImpl){
UserDaoImpl userDao= (UserDaoImpl) bean;
userDao.setName("haohao");
}
System.out.println(beanName+" postProcessBeforeInitialization");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+" postProcessAfterInitialization");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}