背景
在实习工作时,部门在完善安全工具中间件来加固项目,其中就有包括基于Mybatis拦截器实现数据脱敏的工具
工作原理如图:
问题
在调用时加密敏感数据时发现报空指针异常,经Debug发现为注入的EncryptManager为空
拦截器部分代码
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
@Component
@Slf4j
public class DbInterceptor implements Interceptor {
@Autowired
private EncryptManager encryptManager; //加密实现类
原因
Mybatis的插件先于spring容器的完全初始化,虽然加了@Component会被扫描加入容器管理,但是此时Mybatis的拦截器DbInterceptor注入的对象EncryptManager是还未初始化到容器的。
所以通过这种方式拿到的bean为空。
解决
在执行拦截方法时从Spring容器获取bean
(无需另外再写初始化类实现InitializingBean接口的afterPropertiesSet()方法以后置的方式向Mybatis拦截器设置bean)
@Override
public Object intercept(Invocation invocation) throws Throwable {
if(ApolloConfigManager.isCrypticSwitch())//通过apollo配置是否开启拦截器
{
if(encryptManager==null) {
encryptManager=ApplicationUtils.getApplicationContext().getBean(EncryptManager.class);
}
return aesIntercept(invocation);
}else{
return invocation.proceed();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。