




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第Springboot使用SPI注冊bean到spring容器的示例代碼目錄MyDriver接口MysqlDriver實(shí)現(xiàn)OracleDriver實(shí)現(xiàn)Controller:新建resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ExtensionLoader
新建META-INF/vtest/全路徑接口名
mysqlDriver=com.MysqlDriver
oracleDriver=com.OracleDriver
MyDriver接口
publicinterfaceMyDriver{
voidgetConnect();
}
MysqlDriver實(shí)現(xiàn)
publicclassMysqlDriverimplementsMyDriver{
@Override
publicvoidgetConnect(){
System.out.println("connect");
}
OracleDriver實(shí)現(xiàn)
publicclassOracleDriverimplementsMyDriver{
@Override
publicvoidgetConnect(){
System.out.println("connect");
}
importorg.springframework.beans.BeansException;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;
importorg.springframework.beans.factory.support.*;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.ApplicationContextAware;
importorg.springframework.context.ConfigurableApplicationContext;
importorg.springframework.util.StringUtils;
importjava.io.BufferedReader;
importjava.io.File;
importjava.io.InputStreamReader;
importjava.lang.reflect.Field;
import.URL;
importjava.nio.charset.StandardCharsets;
importjava.util.Enumeration;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.concurrent.ConcurrentHashMap;
publicclassExtensionLoaderimplementsBeanDefinitionRegistryPostProcessor,ApplicationContextAware{
ApplicationContextcontext;
BeanDefinitionRegistrybeanDefinitionRegistry;
ConcurrentHashMapClass,MapString,ObjectEXTENSIONS=newConcurrentHashMap();
privatestaticfinalStringSPI_DIRECTORY="META-INF/vtest/";
@Override
publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{
this.context=applicationContext;
ConfigurableApplicationContextconfigurableApplicationContext=(ConfigurableApplicationContext)context;
beanDefinitionRegistry=(DefaultListableBeanFactory)configurableApplicationContext.getBeanFactory();
@Override
publicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistrybeanDefinitionRegistry)throwsBeansException{
try{
ClassLoaderclassLoader=DefaultListableBeanFactory.class.getClassLoader();
URLresource;
File[]files;
if(classLoader!=null){
resource=classLoader.getResource(this.SPI_DIRECTORY);
}else{
resource=ClassLoader.getSystemResource(this.SPI_DIRECTORY);
files=newFile(resource.getFile()).listFiles();
for(inti=0;ifiles.length;i++){
Classclazz=Class.forName(files[i].getName(),true,classLoader);
EXTENSIONS.putIfAbsent(clazz,loadExtensionClass(clazz.getName()));
}catch(Exceptione){
e.printStackTrace();
@Override
publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactoryconfigurableListableBeanFactory)throwsBeansException{
*獲取某個(gè)接口類型對應(yīng)的實(shí)現(xiàn)
*@paramtype
*@return
publicMapString,ObjectgetExtensions(Classtype){
if(null==type){
thrownewIllegalArgumentException("ExtensionClassisnull");
if(!type.isInterface()){
thrownewIllegalArgumentException("ExtensionClassisnotaninterface");
MapString,Objectloader=EXTENSIONS.get(type);
if(loader==null){
synchronized(ExtensionLoader.class){
loader=EXTENSIONS.get(type);
if(loader==null){
EXTENSIONS.putIfAbsent(type,loadExtensionClass(type.getName()));
loader=EXTENSIONS.get(type);
returnloader;
*從擴(kuò)展文件中加載類
*@paramtype
*@return
privateMapString,ObjectloadExtensionClass(Stringtype){
MapString,ObjectextensionClasses=newHashMap();
loadDirectory(extensionClasses,SPI_DIRECTORY,type);
returnextensionClasses;
*加載文件夾
*@paramextensionClasses
*@paramdir
*@paramtype
privatevoidloadDirectory(MapString,ObjectextensionClasses,Stringdir,Stringtype){
StringfileName=dir+type;
try{
EnumerationURLurls;
ClassLoaderclassLoader=DefaultListableBeanFactory.class.getClassLoader();
if(classLoader!=null){
urls=classLoader.getResources(fileName);
}else{
urls=ClassLoader.getSystemResources(fileName);
if(urls!=null){
while(urls.hasMoreElements()){
URLresourcesURL=urls.nextElement();
loadResources(extensionClasses,classLoader,resourcesURL);
}catch(Throwablet){
privatevoidloadResources(MapString,ObjectextensionClasses,ClassLoaderclassLoader,URLresourceURL){
try{
try(BufferedReaderreader=newBufferedReader(newInputStreamReader(resourceURL.openStream(),StandardCharsets.UTF_8))){
Stringline;
while((line=reader.readLine())!=null){
finalintci=line.indexOf('#');
if(ci=0){
line=line.substring(0,ci);
line=line.trim();
if(line.length()0){
try{
Stringname=null;
inti=line.indexOf('=');
if(i0){
name=line.substring(0,i).trim();
line=line.substring(i+1).trim();
if(line.length()0){
loadClass(extensionClasses,resourceURL,Class.forName(line,true,classLoader),name);
}catch(Throwablet){
IllegalStateExceptione=newIllegalStateException("Failedtoloadextensionclass(classline:"+line+")in"+resourceURL+",cause:"+t.getMessage(),t);
}catch(Throwablet){
privatevoidloadClass(MapString,ObjectextensionClasses,.URLresourceURL,Classclazz,Stringname){
if(StringUtils.isEmpty(name)){
thrownewIllegalStateException("Nosuchextensionnamefortheclass"+name+"intheconfig"+resourceURL);
Objecto=extensionClasses.get(name);
if(o==null){
Objectbean=injectBeanToSpring(name,clazz);
extensionClasses.put(name,bean);
}else{
thrownewIllegalStateException("Duplicateextensionname"+name+"on"+clazz.getName()+"and"+clazz.getName());
*動(dòng)態(tài)注入bean到spring容器
*@paramname
*@paramobj
*@return
privateObjectinjectBeanToSpring(Stringname,Classobj){
StringbeanName=name;
BeanDefinitionBuilderbuilder=BeanDefinitionBuilder.genericBeanDefinition(obj);
GenericBeanDefinitiondefinition=(GenericBeanDefinition)builder.getRawBeanDefinition();
definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_NAME);
beanDefinitionRegistry.registerBeanDefinition(beanName,definition);
//TODO:2025/1/9這里動(dòng)態(tài)注入的bean并未將內(nèi)部的@Autowired的bean依賴注入進(jìn)去,如何解決?
//通過反射設(shè)置@Autowired標(biāo)記的字段的值
Objectbean=context.getBean(beanName);
Field[]declaredFields=obj.getDeclaredFields();
for(Fieldfield:declaredFields){
if(field.isAnnotationPresent(Autowired.class)){
ObjectaClass=context.getBean(field.getType());
ReflectHelper.setFieldValue(bean,field.getName(),aClass);
returnbean;
publicclassReflectHelper{
*利用反射獲取指定對象的指定屬性
*@paramobj目標(biāo)對象
*@paramfieldName目標(biāo)屬性
*@return目標(biāo)屬性的值
publicstaticObjectgetFieldValue(Objectobj,StringfieldName){
Objectresult=null;
Fieldfield=ReflectHelper.getField(obj,fieldName);
if(field!=null){
field.setAccessible(true);
try{
result=field.get(obj);
}catch(IllegalArgumentExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
returnresult;
*利用反射獲取指定對象里面的指定屬性
*@paramobj目標(biāo)對象
*@paramfieldName目標(biāo)屬性
*@return目標(biāo)字段
privatestaticFieldgetField(Objectobj,StringfieldName){
Fieldfield=null;
for(Classclazz=obj.getClass();clazz!=Object.class;clazz=clazz.getSuperclass()){
try{
field=clazz.getDeclaredField(fieldName);
break;
}catch(NoSuchFieldExceptione){
//這里不用做處理,子類沒有該字段可能對應(yīng)的父類有,都沒有就返回null。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 行政法學(xué)案例探討與答案發(fā)布
- 2025年衛(wèi)生資格考試復(fù)習(xí)指南與試題及答案
- 2025年執(zhí)業(yè)藥師復(fù)習(xí)時(shí)的常見問題試題及答案
- 行政管理??圃囶}及答案預(yù)測
- 2025年執(zhí)業(yè)藥師考試知識積累試題及答案
- 行政法學(xué)考試知識要點(diǎn)及答案
- 大學(xué)語文重要考點(diǎn)與試題答案
- 快速記憶2025年主管護(hù)師考試試題及答案
- 基本護(hù)理技能考點(diǎn)與試題及答案
- 2025年戶外照明燈具項(xiàng)目規(guī)劃申請報(bào)告模本
- 非遺檔案資源管理系統(tǒng)建設(shè)與實(shí)施研究
- 工傷賠償私了協(xié)議書范本
- 外研版(三起)(2024)三年級下冊英語Unit 5 單元測試卷(含答案)
- 幼兒保育專業(yè)課件
- 畜牧業(yè)人才培養(yǎng)的新機(jī)遇與發(fā)展路徑
- 2025年廣東省中考模擬英語試卷(二)(原卷版+解析版)
- 環(huán)境監(jiān)測信息化建設(shè)-深度研究
- 上海市2022年中考英語卷試題真題及答案詳解
- 知識產(chǎn)權(quán)法律風(fēng)險(xiǎn)防范與應(yīng)對
- 動(dòng)靜脈內(nèi)瘺的建立與維護(hù)課件
- 2025年江蘇鳳凰新華書店集團(tuán)有限公司招聘筆試參考題庫含答案解析
評論
0/150
提交評論