Spring扩展接口知识总结
一、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; }
到此这篇关于Spring扩展接口知识总结的文章就介绍到这了,更多相关Spring扩展接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot ScheduledTaskRegistrar解决动态定时任务思路详解
本文将从问题出发,详细介绍ScheduledTaskRegistrar类是如何解决动态调整定时任务的思路,并给出关键的代码示例,帮助大家快速地上手学习2023-02-02Springboot使用@WebListener 作为web监听器的过程解析
这篇文章主要介绍了Springboot使用@WebListener作为web监听器的过程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-08-08springboot日志文件名称叫logback-spring.xml的原因解析
这篇文章主要介绍了springboot日志文件名称为什么叫logback-spring.xml,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-08-08
最新评论