经典的无法拦截内部方法调用案例:
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;
@Component
public class MenuService {
@Cacheable(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;
@Component
public class MenuService {
@Cacheable(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;
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext ctx;
public static ApplicationContext getContext() {
return ctx;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx = applicationContext;
}
}