基本问题已经定位
@Around("execution(* org.springframework.data.redis.core.RedisTemplate.*(..))")
public Object rtAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("exec RedisTemplate-------------------");
对RedisTemplate的方法做AOP,但始终无法生效
@Autowired
private RedisTemplate redisTemplate;
public void run(){
System.out.println("redisTemplate class:" + redisTemplate.getClass().getName());
ValueOperations valueOperations = redisTemplate.opsForValue();
System.out.println("=======================");
valueOperations.set("xxxname", "xxxx", TimeUnit.SECONDS.toSeconds(60));
}
调用valueOperations.set方法,valueOperations持有redisTemplate实例,底层还是调用redisTemplate的execute方法,但valueOperations中的redisTemplate实例是普通实例,而不是cglib实例,通过@Autowired注入的实例是cglib实例。
问题其实已经找到。
调用redisTemplate.opsForValue();方法时,其实是调用的cglib代理实例的方法,因此会打印exec RedisTemplate。但看redisTemplate.opsForValue()这个方法的内部实现
@Override
public ValueOperations<K, V> opsForValue() {
if (valueOps == null) {
valueOps = new DefaultValueOperations<>(this);
}
return valueOps;
}
代理方法及自定义的aop代码执行后执行redisTemplate普通对象的opsForValue()方法,此时的this并不是代理对象,所以后续调用set方法时使用的redisTemolate对象始终是普通对象并不是代理对象,所以exec RedisTemplate不会再打印。
但现在就是想对redisTemplate埋点,有解决方法么?
@Around("execution(* org.springframework.data.redis.core.RedisTemplate.*(..))")
你确定清楚这句代码的意思?
感觉问题出在这里,,你想用AOP调试springframework的方法??
引入的是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring-boot-starter-data-redis引入
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.10.RELEASE</version>
我试了,第一次执行redisTemplate.opsForValue()的时候走的cglib代理对象AOP是生效的,打印了“====================”,但通过valueOperations.set方法,此时valueOperations中template对象是被代理对象,所有后续AOP都失效了,因为valueOperations中的template是this,是被代理对象。这个已经通过debug确认了。