Springboot使用SPI注冊bean到spring容器的示例代碼_第1頁
Springboot使用SPI注冊bean到spring容器的示例代碼_第2頁
Springboot使用SPI注冊bean到spring容器的示例代碼_第3頁
Springboot使用SPI注冊bean到spring容器的示例代碼_第4頁
Springboot使用SPI注冊bean到spring容器的示例代碼_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論