Spring扩展接口知识总结

网友投稿 278 2023-01-12

Spring扩展接口知识总结

一、BeanPostProcessor

BeanPostProcessor 接口是 Spring 提供的众多接口之一,他的作用主要是如果需要在Spring 容器完成 Bean 的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,可以通过实现 BeanPostProcessor 来完成。

public interface BeanPostProcessor {

@Nullable

default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

// bean初始化方http://法调用前被调用

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 方法在构造函数方法之后执行。

三、InitialingBeankXpYszNJ和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 {

// 获取类对象

@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 extends SqlSessionDaoSupport implements FactoryBean {

@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;

}

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

上一篇:众凯物流查询(亿凯物流客服电话)
下一篇:德国代购快递物流查询单号(德国快递怎么查询)
相关文章

 发表评论

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