需求是在mybatis拦截器中注入RedisUtils用来缓存一些信息。
拦截器
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class MybatisInterceptor implements Interceptor {private static final String CONFIG_KEY = "config";private static Map<String, Map<String, Config>> configMap;@Autowiredprivate RedisUtils redisUtils;@PostConstructpublic void init() {initializeMap();}private synchronized void initializeMap() {String ConfigStr = redisUtils.getValue(CONFIG_KEY);}@Overridepublic Object intercept(Invocation invocation) throws Throwable {String ConfigStr = redisUtils.getValue(CONFIG_KEY);...}...
}
配置类
@Configuration
@AutoConfigureAfter({PageHelperAutoConfiguration.class})
public class MybatisInterceptorConfig {@Autowiredprivate List<SqlSessionFactory> sqlSessionFactoryList;public MybatisInterceptorConfig() {}@PostConstructpublic void addMyInterceptor() {MybatisInterceptor mybatisInterceptor = new MybatisInterceptor();Iterator iterator = this.sqlSessionFactoryList.iterator();while(iterator .hasNext()) {SqlSessionFactory sqlSessionFactory = (SqlSessionFactory)var2.next();sqlSessionFactory.getConfiguration().addInterceptor(mybatisInterceptor);}}
}
调试时发现在mybatis拦截器定义的注解@PostConstruct方法中RedisUtils依赖已经注入,但是在拦截器的Intercept方法中redisUtils为null。
在配置类中将MybatisInterceptor改成@Bean注入后,Intercept执行时依赖问题解决
@Configuration
@AutoConfigureAfter({PageHelperAutoConfiguration.class})
public class MybatisInterceptorConfig {@Autowiredprivate List<SqlSessionFactory> sqlSessionFactoryList;@Beanpublic MybatisInterceptor mybatisInterceptor() {return new MybatisInterceptor();}@PostConstructpublic void addMyInterceptor() {MybatisInterceptor mybatisInterceptor = mybatisInterceptor();Iterator iterator = this.sqlSessionFactoryList.iterator();while(iterator .hasNext()) {SqlSessionFactory sqlSessionFactory = (SqlSessionFactory)var2.next();sqlSessionFactory.getConfiguration().addInterceptor(mybatisInterceptor);}}
}
其原因个人推测是通过@Component注入虽然可以将依赖注入到spring中,但是SqlSessionFactory.getConfiguration()中的拦截器是通过new设置的,在执行@PostConstruct初始化方法时用的时spring中注入的MybatisInterceptor,而在执行Intercept拦截时用的时new出的实例方法。因此将配置类中的MybatisInterceptor bean设置到SqlSessionFactory中即可。