您好,登錄后才能下訂單哦!
這篇文章給大家介紹Spring有哪些擴展接口,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
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 接口與 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 方法在構造函數方法之后執行。
InitializingBean 接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet 方法,凡是繼承該接口的類,在初始化bean的時候都會執行該方法。
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
DisposableBean 也是一個接口,提供了一個唯一的方法destory(),凡是繼承該接口的類,在Bean生命周期結束前都會執行該方法。
public interface DisposableBean { void destroy() throws Exception; }
這里借用網上的一張Bean生命周期的過程圖片:
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 可以完成新的 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); } }
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有哪些擴展接口就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。