Spring扩展接口 Spring扩展接口知识总结
普通人zzz~ 人气:0一、BeanPostProcessor
BeanPostProcessor 接口是 Spring 提供的众多接口之一,他的作用主要是如果需要在Spring 容器完成 Bean 的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,可以通过实现 BeanPostProcessor 来完成。
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // bean初始化方法调用前被调用 return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // bean初始化方法调用后被调用 return bean; } }
运行顺序:
----------------Spring IOC容器实例化Bean ----------------调用BeanPostProcessor的postProcessBeforeInitialization方法 ----------------调用bean实例的初始化方法 ----------------调用BeanPostProcessor的postProcessAfterInitialization方法
二、BeanFactoryPostProcessor
BeanFactoryPostProcessor 接口与 BeanPostProcessor 接口类似,可以对bean的定义(配置元数据)进行处理;也就是spring ioc运行BeanFactoryPostProcessor 在容器实例化任何其他的bean之前读取配置元数据,并有可能修改它;
如果业务需要,可以配置多个BeanFactoryPostProcessor 的实现类,通过 ”order” 控制执行次序(要实现 Ordered 接口)。
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public MyBeanFactoryPostProcessor() { System.out.println("----------------execute MyBeanFactoryPostProcessor constructor"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("----------------execute MyBeanFactoryPostProcessor postProcessBeanFactory"); } }
打印输出:
----------------execute MyBeanFactoryPostProcessor constructor
----------------execute MyBeanFactoryPostProcessor postProcessBeanFactory
postProcessBeanFactory 方法在构造函数方法之后执行。
三、InitialingBean和DisposableBean
InitializingBean 接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet 方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
DisposableBean 也是一个接口,提供了一个唯一的方法destory(),凡是继承该接口的类,在Bean生命周期结束前都会执行该方法。
public interface DisposableBean { void destroy() throws Exception; }
这里借用网上的一张Bean生命周期的过程图片:
四、FactoryBean
FactoryBean 是一个接口,当在 IOC 容器中的 Bean 实现了 FactoryBean 后,通过 getBean(String BeanName) 获取到的Bean对象并不是 FactoryBean 的实现类对象,而是这个实现类中的 getObject() 方法返回的对象。
public interface FactoryBean<T> { // 获取类对象 @Nullable T getObject() throws Exception; // 获取类类型 @Nullable Class<?> getObjectType(); // 是否单例 default boolean isSingleton() { return true; } }
五、BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 可以完成新的 BeanDefinition 注册,对已有 BeanDefinition 进行修改等操作。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * 在Spring的标准初始化完成之后,此时所有的符合 Spring 规则的BeanDefinition已经全部完成加载,但是还没有任何一个 Bean 被初始化, * Spring允许在下一个post-processing开始处理之前通过此接口添加更多的BeanDefinition */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
写一个类实现 BeanDefinitionRegistryPostProcessor 往容器中手动注册一个BeanDefinition。
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { // 创建一个bean的定义类的对象 RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(MyMapperFactoryBean.class); // 将Bean 的定义注册到Spring环境 beanDefinitionRegistry.registerBeanDefinition("myMapperFactoryBean", rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// bean的名字为key, bean的实例为value } }
MyMapperFactoryBean :
public class MyMapperFactoryBean implements FactoryBean { @Override public Object getObject() throws Exception { // 创建一个代理对象 return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{TestBeanDefRegPostProMapper.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("----------execute:" + method.getName()); Class<?> returnType = method.getReturnType(); return "xxxxxxxxxxxx"; } }); } @Override public Class<?> getObjectType() { return TestBeanDefRegPostProMapper.class; } }
TestBeanDefRegPostProMapper 接口:
public interface TestBeanDefRegPostProMapper { String exexute(); }
测试:
@SpringBootApplication public class SpringbootApplication implements CommandLineRunner { @Autowired private TestBeanDefRegPostProMapper testBeanDefRegPostProMapper; public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } @Override public void run(String... args) throws Exception { System.out.println(testBeanDefRegPostProMapper.exexute()); } }
测试结果:
----------execute:exexute
xxxxxxxxxxxx
最经典的案例就是Mybatis与Spring集成中的 MapperScannerConfigurer 和 MapperFactoryBean
MapperScannerConfigurer :
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.registerFilters(); // 扫描Mybatis配置MapperScan包,进行注册,将每一个Mapper接口都注册为一个MapperFactoryBean对象 scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); } }
MapperFactoryBean:
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> { @Override public T getObject() throws Exception { // 返回一个代理对象,用于执行sql return getSqlSession().getMapper(this.mapperInterface); } }
六、BeanNameAware、ApplicationContextAware 和 BeanFactoryAware
1、实现 BeanNameAware 接口的 Bean,在 Bean 加载的过程中可以获取到该 Bean 的 id。
public interface BeanNameAware extends Aware { void setBeanName(String beanName); }
2、实现 ApplicationContextAware 接口的 Bean,在 Bean 加载的过程中可以获取到 Spring的ApplicationContext,ApplicationContext 是 Spring 应用上下文,从 ApplicationContext 中可以获取包括任意的 Bean 在内的大量 Spring 容器内容和信息。
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
3、实现 BeanFactoryAware 接口的 Bean,在 Bean 加载的过程中可以获取到加载该 Bean的BeanFactory。
public interface BeanFactoryAware extends Aware { void setBeanFactory(BeanFactory beanFactory) throws BeansException; }
加载全部内容