dubbo filter中有关bean注入和配置文件读取方式
作者:weixin_45614626
dubbo filter中有关bean注入和配置文件读取
在写dubbo的filter时候,需要注入bean和读取配置文件,然后理所当然的就像springboot其他地方的写法一样,直接用了@Resource和@Value注解。
但是本地调试的时候,发现报错,注入的bean和读取的配置变量全部为null,很是不解,于是就上网查了以下资料。
首先,dubbo的拦截器这些组件是由dubbo自己管理的,并不是直接由spring管理的,因此spring的那些注入注解在dubbo里统统不能用。
如果想用可以采取以下代码:
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组件实例化后,setter方法会被dubbo调起,然后在ApplicationContext中去查找对应的bean。
而且在查找的过程中是优先按照名字去匹配,然后才是type,所以尽量把setter方法名字写成要注入的bean的名字。
能够注入Bean的Filter
DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。
DelegatingFilterProxy运用
需求:
在springboot中 使用了filter, 并且注入了业务工具类(APIUtil ),但注入是null
所以问题就来了:springboot中使用filter时注入bean为null的解决办法
其实Spring中,web应用启动的顺序是:listener->filter->servlet,先初始化listener,然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化
解决办法1
public class TokenAuthFilter implements Filter { private final static Logger log = LoggerFactory.getLogger(TokenAuthFilter.class); @Autowired private APIUtil apiUtil; }
新增一个config类,用来手工创建filter的bean, 例如:
@Configuration public class WebConfig { @Bean public Filter tokenAuthFilter() { return new TokenAuthFilter(); //第一步:先将filter放入容器 } /** * 注册filter,统一处理api开头的请求 * @return FilterRegistrationBean */ @Bean public FilterRegistrationBean tokenAuthFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); // 第二步:DelegatingFilterProxy把servlet 容器中的filter同spring容器中的bean关联起来 registration.setFilter(new DelegatingFilterProxy("tokenAuthFilter")); registration.addUrlPatterns("/api/*"); registration.setName("tokenAuthFilter"); registration.setOrder(1); return registration; } }
解决办法2
过滤器是servlet规范中定义的,并不归spring容器管理,也无法直接注入spring中的bean(会报错)
初始化时通过spring上下文获取,进行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); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。