dubbo?filter中有關(guān)bean注入和配置文件讀取方式
dubbo filter中有關(guān)bean注入和配置文件讀取
在寫(xiě)dubbo的filter時(shí)候,需要注入bean和讀取配置文件,然后理所當(dāng)然的就像springboot其他地方的寫(xiě)法一樣,直接用了@Resource和@Value注解。
但是本地調(diào)試的時(shí)候,發(fā)現(xiàn)報(bào)錯(cuò),注入的bean和讀取的配置變量全部為null,很是不解,于是就上網(wǎng)查了以下資料。
首先,dubbo的攔截器這些組件是由dubbo自己管理的,并不是直接由spring管理的,因此spring的那些注入注解在dubbo里統(tǒng)統(tǒng)不能用。
如果想用可以采取以下代碼:
private Environment environment; public void setEnvironment(Environment environment){ this.environment=environment; } @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { String headerTopic = environment.getProperty("spring.kafka.header-topic"); Result result = invoker.invoke(invocation); return result; }
這樣就可以讀取到配置文件了。
如果想要注入bean,則使用以下代碼:
private KafkaTemplate<String, String> headKafkaTemplate; public void setHeadKafkaTemplate(KafkaTemplate<String, String> headKafkaTemplate){ this.headKafkaTemplate = headKafkaTemplate; }
dubbo組件實(shí)例化后,setter方法會(huì)被dubbo調(diào)起,然后在ApplicationContext中去查找對(duì)應(yīng)的bean。
而且在查找的過(guò)程中是優(yōu)先按照名字去匹配,然后才是type,所以盡量把setter方法名字寫(xiě)成要注入的bean的名字。
能夠注入Bean的Filter
DelegatingFilterProxy就是一個(gè)對(duì)于servlet filter的代理,用這個(gè)類(lèi)的好處主要是通過(guò)Spring容器來(lái)管理servlet filter的生命周期,還有就是如果filter中需要一些Spring容器的實(shí)例,可以通過(guò)spring直接注入,另外讀取一些配置文件這些便利的操作都可以通過(guò)Spring來(lái)配置實(shí)現(xiàn)。
DelegatingFilterProxy運(yùn)用
需求:
在springboot中 使用了filter, 并且注入了業(yè)務(wù)工具類(lèi)(APIUtil ),但注入是null
所以問(wèn)題就來(lái)了:springboot中使用filter時(shí)注入bean為null的解決辦法
其實(shí)Spring中,web應(yīng)用啟動(dòng)的順序是:listener->filter->servlet,先初始化listener,然后再來(lái)就filter的初始化,再接著才到我們的dispathServlet的初始化
解決辦法1
public class TokenAuthFilter implements Filter { private final static Logger log = LoggerFactory.getLogger(TokenAuthFilter.class); @Autowired private APIUtil apiUtil; }
新增一個(gè)config類(lèi),用來(lái)手工創(chuàng)建filter的bean, 例如:
@Configuration public class WebConfig { @Bean public Filter tokenAuthFilter() { return new TokenAuthFilter(); //第一步:先將filter放入容器 } /** * 注冊(cè)filter,統(tǒng)一處理api開(kāi)頭的請(qǐng)求 * @return FilterRegistrationBean */ @Bean public FilterRegistrationBean tokenAuthFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); // 第二步:DelegatingFilterProxy把servlet 容器中的filter同spring容器中的bean關(guān)聯(lián)起來(lái) registration.setFilter(new DelegatingFilterProxy("tokenAuthFilter")); registration.addUrlPatterns("/api/*"); registration.setName("tokenAuthFilter"); registration.setOrder(1); return registration; } }
解決辦法2
過(guò)濾器是servlet規(guī)范中定義的,并不歸spring容器管理,也無(wú)法直接注入spring中的bean(會(huì)報(bào)錯(cuò))
初始化時(shí)通過(guò)spring上下文獲取,進(jìn)行bean的初始化:
@Override public void init(FilterConfig filterConfig) throws ServletException { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext()); RedisTemplate demoBean = (RedisTemplate)context.getBean("redisTemplate"); System.out.println(demoBean); }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java工廠模式用法之如何動(dòng)態(tài)選擇對(duì)象詳解
工廠設(shè)計(jì)模式可能是最常用的設(shè)計(jì)模式之一,我想大家在自己的項(xiàng)目中都用到過(guò)。本文不僅僅是關(guān)于工廠模式的基本知識(shí),更是討論如何在運(yùn)行時(shí)動(dòng)態(tài)選擇不同的方法進(jìn)行執(zhí)行,你們可以看看是不是和你們項(xiàng)目中用的一樣2023-03-03通過(guò)Feign進(jìn)行調(diào)用@FeignClient?找不到的解決方案
這篇文章主要介紹了通過(guò)Feign進(jìn)行調(diào)用@FeignClient?找不到的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot實(shí)現(xiàn)前后端分離國(guó)際化的示例詳解
Springboot國(guó)際化可以幫助使用者在不同語(yǔ)言環(huán)境中構(gòu)建應(yīng)用程序,這樣應(yīng)用程序可以有效地適應(yīng)不同語(yǔ)言文化背景下的用戶需求。本文主要介紹了SpringBoot實(shí)現(xiàn)前后端分離國(guó)際化的方法,需要的可以參考一下2023-02-02Java Web文件上傳與下載優(yōu)化的實(shí)現(xiàn)方案
文件上傳與下載是 Web 應(yīng)用中常見(jiàn)的功能,尤其是在需要處理大量文件傳輸、存儲(chǔ)的場(chǎng)景下,傳統(tǒng)的文件上傳和下載方式雖然簡(jiǎn)單,但如果不加以?xún)?yōu)化,可能會(huì)帶來(lái)一些問(wèn)題,所以今天,我們將深入探討 Java Web 中如何實(shí)現(xiàn)高效的文件上傳和下載,需要的朋友可以參考下2025-02-02SpringBoot加載應(yīng)用事件監(jiān)聽(tīng)器代碼實(shí)例
這篇文章主要介紹了SpringBoot加載應(yīng)用事件監(jiān)聽(tīng)器代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06