Spring動態(tài)加載bean后調(diào)用實現(xiàn)方法解析
前言
在使用Spring的過程中,我們有時候并不想通過xml的方式進行bean的注入,希望在不改變原有的程序結(jié)構(gòu)的基礎(chǔ)上添加我們需要的bean,這個時候我們可以利用Spring的spring-beans的jar包里提供的BeanFactoryPostProcessor接口類,通過實現(xiàn)這個接口類,我們可以動態(tài)的加載所需要的bean,特別是在引入已經(jīng)打包在jar里面的程序而沒有辦法做出修改的情況下,這個接口就為我們提供了及其方便的入口。
因為我是在其他項目的基礎(chǔ)上測試的這個接口,所以引入的jar有其特殊性,所以需要參考的同學可以按照自己的需求來實現(xiàn)。
1.通過pom.xml來引入springboot:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.thread</groupId> <artifactId>test</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>f:/threadTest.jar</systemPath> </dependency> </dependencies>
2.創(chuàng)建App.java啟動類:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author liaoyubo * @version 1.0 2017/7/31 * @description */ @SpringBootApplication public class App { public static void main(String [] args){ SpringApplication.run(App.class); } }
3.創(chuàng)建一個DynamicCreateBean.java來作為動態(tài)加載的對象:
public class DynamicCreateBean { public void printMethod(){ System.out.println("DynamicCreateBean Success"); } }
4.在本項目外另外新增一個項目打成jar的形式導入到該項目中用于測試動態(tài)加載,在我的項目中新增的是threadTest.jar,該包是一個用于多線程測試的類,需要的同學自己隨便新建一個來打成jar包測試即可。
5.新增一個LoadBean.java類用于動態(tài)加載bean:
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.stereotype.Component; import com.thread.mulitSynThreadTest.Run; /** * @author liaoyubo * @version 1.0 2017/8/11 * @description */ @Component public class LoadBean implements BeanFactoryPostProcessor { private DefaultListableBeanFactory defaultListableBeanFactory; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { this.defaultListableBeanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory; BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition("com.springRedis.dynamic.DynamicCreateBean"); //用于設(shè)置指定的類中需要引入的其他bean //beanDefinitionBuilder.addPropertyValue("otherBeanName","otherBeanName"); this.defaultListableBeanFactory.registerBeanDefinition("dynamicCreateBean",beanDefinitionBuilder.getBeanDefinition()); beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Run.class.getName()); //用于設(shè)置指定的類中需要引入的其他bean //beanDefinitionBuilder.addPropertyValue("otherBeanName","otherBeanName"); this.defaultListableBeanFactory.registerBeanDefinition("mulitRun",beanDefinitionBuilder.getBeanDefinition()); } }
6.創(chuàng)建測試類:
import com.springRedis.App; import com.springRedis.dynamic.DynamicCreateBean; import com.thread.mulitSynThreadTest.Run; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * @author liaoyubo * @version 1.0 2017/8/11 * @description */ @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class MultiTest { @Autowired private DynamicCreateBean dynamicCreateBean; @Autowired private Run run; @Test public void testDynamic(){ dynamicCreateBean.printMethod(); run.printRun(); } }
以上就是整個的動態(tài)加載過程,如果需要了解更多,可以在網(wǎng)上繼續(xù)查找資料。
最近在看spring cloud Feign相關(guān)文章時發(fā)現(xiàn)了另外一種注入動態(tài)bean的方式,里面的代碼提供是在FeignClientsRegistrar.java類中
具體代碼為:
private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) { String className = annotationMetadata.getClassName(); BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class); this.validate(attributes); definition.addPropertyValue("url", this.getUrl(attributes)); definition.addPropertyValue("path", this.getPath(attributes)); String name = this.getName(attributes); definition.addPropertyValue("name", name); definition.addPropertyValue("type", className); definition.addPropertyValue("decode404", attributes.get("decode404")); definition.addPropertyValue("fallback", attributes.get("fallback")); definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory")); definition.setAutowireMode(2); String alias = name + "FeignClient"; AbstractBeanDefinition beanDefinition = definition.getBeanDefinition(); boolean primary = ((Boolean)attributes.get("primary")).booleanValue(); beanDefinition.setPrimary(primary); String qualifier = this.getQualifier(attributes); if(StringUtils.hasText(qualifier)) { alias = qualifier; } BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias}); BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Cloud構(gòu)建Eureka應(yīng)用的方法
這篇文章主要介紹了Spring Cloud構(gòu)建Eureka應(yīng)用的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03java實現(xiàn)TCP socket和UDP socket的實例
這篇文章主要介紹了本文主要介紹了java實現(xiàn)TCP socket和UDP socket的實例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02JeecgBoot框架升級至Spring?Boot3的實戰(zhàn)步驟
本文主要介紹了JeecgBoot框架升級至Spring?Boot3的實戰(zhàn)步驟,從?2.7.10升級到3.1.5有以下幾個點需要注意,下面就來詳細的介紹一下,感興趣的可以了解一下2024-04-04深入解析Spring Cloud內(nèi)置的Zuul過濾器
這篇文章主要給大家深入的介紹了Spring Cloud內(nèi)置的Zuul過濾器的相關(guān)資料,文中給大家介紹的很詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-02-02Apache?Commons?Config管理配置文件核心功能使用
這篇文章主要為大家介紹了Apache?Commons?Config管理和使用配置文件核心深入探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12java和javascript中過濾掉img形式的字符串不顯示圖片的方法
這篇文章主要介紹了java和javascript中過濾掉img形式的字符串不顯示圖片的方法,以實例形式分別講述了采用java和javascript實現(xiàn)過濾掉img形式字符串的技巧,需要的朋友可以參考下2015-02-02