Spring擴展接口知識總結
一、BeanPostProcessor
BeanPostProcessor 接口是 Spring 提供的眾多接口之一,他的作用主要是如果需要在Spring 容器完成 Bean 的實例化、配置和其他的初始化前后添加一些自己的邏輯處理,可以通過實現(xiàn) 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的定義(配置元數(shù)據)進行處理;也就是spring ioc運行BeanFactoryPostProcessor 在容器實例化任何其他的bean之前讀取配置元數(shù)據,并有可能修改它;
如果業(yè)務需要,可以配置多個BeanFactoryPostProcessor 的實現(xiàn)類,通過 ”order” 控制執(zhí)行次序(要實現(xiàn) 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 方法在構造函數(shù)方法之后執(zhí)行。
三、InitialingBean和DisposableBean
InitializingBean 接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet 方法,凡是繼承該接口的類,在初始化bean的時候都會執(zhí)行該方法。
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
DisposableBean 也是一個接口,提供了一個唯一的方法destory(),凡是繼承該接口的類,在Bean生命周期結束前都會執(zhí)行該方法。
public interface DisposableBean {
void destroy() throws Exception;
}
這里借用網上的一張Bean生命周期的過程圖片:

四、FactoryBean
FactoryBean 是一個接口,當在 IOC 容器中的 Bean 實現(xiàn)了 FactoryBean 后,通過 getBean(String BeanName) 獲取到的Bean對象并不是 FactoryBean 的實現(xiàn)類對象,而是這個實現(xiàn)類中的 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 規(guī)則的BeanDefinition已經全部完成加載,但是還沒有任何一個 Bean 被初始化,
* Spring允許在下一個post-processing開始處理之前通過此接口添加更多的BeanDefinition
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
寫一個類實現(xiàn) BeanDefinitionRegistryPostProcessor 往容器中手動注冊一個BeanDefinition。
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 創(chuàng)建一個bean的定義類的對象
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(MyMapperFactoryBean.class);
// 將Bean 的定義注冊到Spring環(huán)境
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 {
// 創(chuàng)建一個代理對象
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 {
// 返回一個代理對象,用于執(zhí)行sql
return getSqlSession().getMapper(this.mapperInterface);
}
}
六、BeanNameAware、ApplicationContextAware 和 BeanFactoryAware
1、實現(xiàn) BeanNameAware 接口的 Bean,在 Bean 加載的過程中可以獲取到該 Bean 的 id。
public interface BeanNameAware extends Aware {
void setBeanName(String beanName);
}
2、實現(xiàn) ApplicationContextAware 接口的 Bean,在 Bean 加載的過程中可以獲取到 Spring的ApplicationContext,ApplicationContext 是 Spring 應用上下文,從 ApplicationContext 中可以獲取包括任意的 Bean 在內的大量 Spring 容器內容和信息。
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
3、實現(xiàn) BeanFactoryAware 接口的 Bean,在 Bean 加載的過程中可以獲取到加載該 Bean的BeanFactory。
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
到此這篇關于Spring擴展接口知識總結的文章就介紹到這了,更多相關Spring擴展接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring mvc服務端數(shù)據校驗實現(xiàn)流程詳解
這篇文章主要介紹了Spring mvc服務端數(shù)據校驗實現(xiàn)流程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09
spring boot項目同時傳遞參數(shù)和文件的多種方式代碼演示
這篇文章主要介紹了spring boot項目同時傳遞參數(shù)和文件的多種方式,在開發(fā)接口中,遇到了需要同時接收參數(shù)和文件的情況,可以有多種方式實現(xiàn)文件+參數(shù)的接收,這里基于spring boot 3 + vue 3 + axios,做一個簡單的代碼演示,需要的朋友可以參考下2023-06-06

