Spring動態(tài)加載bean后調(diào)用實現(xiàn)方法解析
前言
在使用Spring的過程中,我們有時候并不想通過xml的方式進行bean的注入,希望在不改變原有的程序結構的基礎上添加我們需要的bean,這個時候我們可以利用Spring的spring-beans的jar包里提供的BeanFactoryPostProcessor接口類,通過實現(xiàn)這個接口類,我們可以動態(tài)的加載所需要的bean,特別是在引入已經(jīng)打包在jar里面的程序而沒有辦法做出修改的情況下,這個接口就為我們提供了及其方便的入口。
因為我是在其他項目的基礎上測試的這個接口,所以引入的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");
//用于設置指定的類中需要引入的其他bean
//beanDefinitionBuilder.addPropertyValue("otherBeanName","otherBeanName");
this.defaultListableBeanFactory.registerBeanDefinition("dynamicCreateBean",beanDefinitionBuilder.getBeanDefinition());
beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Run.class.getName());
//用于設置指定的類中需要引入的其他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相關文章時發(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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
java實現(xiàn)TCP socket和UDP socket的實例
這篇文章主要介紹了本文主要介紹了java實現(xiàn)TCP socket和UDP socket的實例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
JeecgBoot框架升級至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過濾器的相關資料,文中給大家介紹的很詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-02-02
Apache?Commons?Config管理配置文件核心功能使用
這篇文章主要為大家介紹了Apache?Commons?Config管理和使用配置文件核心深入探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12
java和javascript中過濾掉img形式的字符串不顯示圖片的方法
這篇文章主要介紹了java和javascript中過濾掉img形式的字符串不顯示圖片的方法,以實例形式分別講述了采用java和javascript實現(xiàn)過濾掉img形式字符串的技巧,需要的朋友可以參考下2015-02-02

