Spring有哪些扩展接口

网友投稿 177 2024-02-02


Spring有哪些扩展接口

本文主要介绍"Spring有哪些扩展接口",希望能够解决您遇到有关问题,下面我们一起来看这篇 "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有哪些扩展接口" 就介绍到这。希望大家多多

Java编程技术


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java中接口是什么意思
下一篇:Netscreen防火墙常用命令-接口篇
相关文章

 发表评论

暂时没有评论,来抢沙发吧~