您好,登錄后才能下訂單哦!
小編給大家分享一下SpringBoot如何實現(xiàn)鉤子接口,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Aware 意為感知,實現(xiàn) Aware 接口并重寫其方法,可以從上下文中獲取當前的運行環(huán)境
常見的 aware 接口
BeanNameAware
BeanFactoryAware
BeanClassLoaderAware
ApplicationContextAware
使用
@Component @ToString public class TestService implements BeanNameAware, BeanClassLoaderAware { private String beanName; private ClassLoader classLoader; @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } @Override public void setBeanName(String name) { this.beanName= name; } }
InitializingBean 接口用于在 Bean 的初始化階段執(zhí)行自定義的操作,類型功能的還有 DisposableBean
使用
@Component public class TestBean implements InitializingBean, DisposableBean { // bean 設(shè)置完屬性之后調(diào)用 @Override public void afterPropertiesSet() throws Exception { // 初始化操作 System.out.println("TestBean init"); } // 銷毀之后調(diào)用 @Override public void destroy() throws Exception { // 釋放資源 System.out.println("TestBean destroy"); } }
BeanPostProcessor,Bean 的后置處理器,與 InitializingBean 不同的是,BeanPostProcessor 對所有 Bean 生效
使用
@Component public class TestPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Bean 初始化前"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Bean 初始化后"); return bean; } }
BeanPostProcessor 使用場景非常多,可以獲取正在初始化的 Bean 對象,然后依據(jù)該 Bean 對象做一些定制化的操作,如:判斷該 Bean 是否為某個特定對象、獲取 Bean 的注解元數(shù)據(jù)等
Spring 內(nèi)置了非常多的 BeanPostProcessor ,以此來完善自身功能
BeanFactoryPostProcessor 是 Bean 工廠的后置處理器,一般用來修改上下文中的 BeanDefinition
使用
@Component public class TestFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("所有 BeanDefinition 已被加載,但還未實例化 Bean"); // 動態(tài)添加 BeanDefinition //轉(zhuǎn)換為子類 DefaultListableBeanFactory DefaultListableBeanFactory defaultBeanFactory = (DefaultListableBeanFactory) beanFactory; //new 一個 beanDefinition對象 GenericBeanDefinition b = new GenericBeanDefinition(); b.setBeanClass(Testbean.class); //添加一個 beanDefinition 對象 defaultBeanFactory.registerBeanDefinition("testBean", b); // 動態(tài)獲取 BeanDefinition Object o = defaultBeanFactory.getBean("testBean") } }
BeanDefinition 包含了 Spring 實例化一個 Bean 的所需的信息
ImportSelector 可以動態(tài)的返回需要被容器管理的類,一般用來返回外部的配置類
public class TestImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // AnnotationMetadata 存儲注解元數(shù)據(jù)信息 // 可以動態(tài)的返回需要被容器管理的類名稱 if (importingClassMetadata.hasAnnotation("")) { // 判斷是否包含某個注解 } // TestBean 加入到 Spring 容器中 return new String[]{"com.example.pojo.TestBean"}; } }
在標注 @Configuration 注解的類中,通過 @Import 導入 ImportSelector 來使之生效
@Configuration @Import(TestImportSelector.class) public class TestConfig { }
ImportBeanDefinitionRegistrar 也是配合 @Import 使用,可直接將 Bean 注冊到容器中
使用
public class TestRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { GenericBeanDefinition b = new GenericBeanDefinition(); b.setBeanClass(NotScanBean.class); b.setLazyInit(true); // 注冊到容器中 registry.registerBeanDefinition(NotScanBean.class.getName(), b); } }
FactoryBean 為創(chuàng)建 Bean 提供了更加靈活的方式,常用于用于創(chuàng)建一類 Bean
Bean 實現(xiàn) FactoryBean 后,通過 getBean(String BeanName) 獲取到的 Bean 對象并不是 FactoryBean 的實現(xiàn)類對象,而是這個實現(xiàn)類中的 getObject() 方法返回的對象,在 BeanName 之前加上 &,可以獲取 FactoryBean 的實現(xiàn)類對象
使用
@Component public class TestFactoryBean implements FactoryBean<TestBean> { @Override public TestBean getObject() throws Exception { // 對 Bean 進行配置 // 如代理、修飾等 return new TestBean(); } @Override public Class<?> getObjectType() { return null; } }
ApplicationListener 是 Spring 實現(xiàn)事件機制的核心接口,屬于觀察者設(shè)計模式
ApplicationContext 可以發(fā)布 ApplicationEvent 事件,之后所有的 ApplicationListener 會被回調(diào)
自定義 ApplicationEvent
public class TestApplicationEvent extends ApplicationEvent { public TestApplicationEvent(Object source) { super(source); } public void hello(){ System.out.println("Hello Word!"); } }
自定義 ApplicationListener
@Component public class TestApplicationListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof TestApplicationEvent) { TestApplicationEvent testApplicationEvent = (TestApplicationEvent) event; testApplicationEvent.hello(); } } }
通過注入 ApplicationContext 或?qū)崿F(xiàn) ApplicationContextAware 接口,獲取 ApplicationContext 對象,發(fā)布 ApplicationEvent
@SpringBootTest class DemoApplicationTests { @Autowired ApplicationContext applicationContext; @Test public void test() { applicationContext.publishEvent(new TestApplicationEvent(new DemoApplication())); } } // Hello Word!
SpringBoot 應用啟動成功會 callRunners 方法,所有 ApplicationRunner 實現(xiàn)類都會被回調(diào)
實現(xiàn) AppilcationRunner,ApplicationArguments 類型用來接收啟動參數(shù)
@Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("原始參數(shù):" + Arrays.asList(args.getSourceArgs())); Set<String> keys = args.getOptionNames(); for (String key : keys) { System.out.println("解析后的 key: [" + key + "] value: " + args.getOptionValues(key)); } System.out.println("無 OptionName 的參數(shù): " + args.getNonOptionArgs()); } } // 例:啟動參數(shù) --a=1 --b c // 打印 => // 原始參數(shù):[--a=1, --b, c] // 解析后的 key: [a] value: [1] // 解析后的 key: [b] value: [] // 無 OptionName 的參數(shù): [c]
CommandLineRunner 和 ApplicationRunner 類似,但是只能獲得沒有經(jīng)過解析的原始參數(shù)
以上是“SpringBoot如何實現(xiàn)鉤子接口”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。