经典的无法拦截内部方法调用案例:
package com.imooc.service;
import com.imooc.config.ApplicationContextHolder;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
public class MenuService {
(cacheNames = {"menu"})
public List<String> getMenuList(){
System.out.println("");
System.out.println("mock:get from db");
return Arrays.asList("article","comment","admin");
}
public List<String> getRecommends(){
return this.getMenuList();
}
}
Ps:不会启动AOP: 因为是通过 this 调用,哪怕该方法上有切面注解,但获取不到Bean的原因,所以注解也会失效。
解决方案:通过代理来调用该方法,而不是通过 this 来调用。
package com.imooc.service;
import com.imooc.config.ApplicationContextHolder;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
public class MenuService {
(cacheNames = {"menu"})
public List<String> getMenuList(){
System.out.println("");
System.out.println("mock:get from db");
return Arrays.asList("article","comment","admin");
}
public List<String> getRecommends(){
MenuService proxy = ApplicationContextHolder.getContext().getBean(MenuService.class);
return proxy.getMenuList();
}
}
package com.imooc.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext ctx;
public static ApplicationContext getContext() {
return ctx;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx = applicationContext;
}
}
- 源码下载地址SpringAOP之探秘(动态代理、责任链模式、注解使用)_spring责任链模式,责任链注解-Java代码类资源-CSDN下载