Aware接口的Bean在被初始之后,可以取得一些相对应的资源。
Aware接口本身并不具备什么功能,一般是用于子类继承后,Spring上下文初始化bean的时候会对这个bean传入需要的资源。
例如ApplicationContextAware接口,可以在Spring初始化实例 Bean的时候,可以通过这个接口将当前的Spring上下文传入。
当一个类实现了这个接口(ApplicationContextAware)以后,这个类就能够方便得到ApplicationContext中的全部bean。换句话说,就是这个类能够直接获取spring配置文件中,全部引用到的bean对象。
注意:一定要让继承ApplicationContextAware接口的bean被Spring上下文管理,在application.xml文件中定义对应的bean标签,或者使用@Component标注。
一.使用步骤
-
实现ApplicationContextAware接口
-
重写setApplicationContext方法:
-
通过applicationContext获取某个类(可以是注解的类):
-
对获取到的类及其中的方法做修改等操作。(利用反射)
二.项目实例
2.1 背景
项目要求需要从oracle数据库迁移到tidb数据库,但是考虑到如果在迁移过程中会出现某个业务sql迁移到tidb数据库后,会出现和原有oracle数据不同甚至直接报错的现象,所以需要有一套回滚方法,当出现问题的时候可以立即切回原oracle数据库,极大的减少出现问题带来的线上影响。
2.2 方案:
使用切面进行路由控制。在切换至tidb数据库时,原oracle数据源保留,jdbi数据源默认执行,通过实现ApplicationContextAware接口,再利用切面(我这的切入点是个注解)拿到对应的数据源value,再在数据库中配置路由表(即配置dao层的类+方法),如果在生产切换到tidb库后遇到问题,可以在数据库中配置路由,根据配置的路由与切面拿到的dao层bean一致,则利用反射动态替换成oracle的dao层bean(tidb的dao后缀的tidbDao,而oracle的后缀是Dao)执行对应的sql, 来达到回滚目的。
2.3 具体代码
package xzh.trace.config
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.reflect.MethodUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import