背景

在实习工作时,部门在完善安全工具中间件来加固项目,其中就有包括基于Mybatis拦截器实现数据脱敏的工具

工作原理如图:image

问题

在调用时加密敏感数据时发现报空指针异常,经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();
            }
    }

J2kong
0 声望1 粉丝