描述:在使用AOP切面的时候Controller层可以正常切入进去,但是Service层内部方法调用切入不进去
大致情况
就算打注解放methodB上也不会进切面,Aop只支持外部调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import org.springframework.stereotype.Service;
@Service public class TestAopService {
public void methodA() { System.out.println("method A run"); methodB(); } public void methodB() { System.out.println("method B run"); } }
|
解决方式
1.配置spring-context.xml
1 2 3 4
| <!-- 通过@Aspect注解实现AOP --> <!-- proxy-target-class="true"表示使用CGlib动态代理 --> <!-- expose-proxy="true"暴露代理对象 --> <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>
|
2.使用AopContext.currentProxy()获取代理对象方法,并且执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import org.springframework.aop.framework.AopContext; import org.springframework.stereotype.Service;
@Service public class TestAopService {
public void methodA() { System.out.println("method A run"); ((TestAopService) AopContext.currentProxy()).methodB(); } public void methodB() { System.out.println("method B run"); } }
|
注意点
methodB一定要声明为public
否则进不去切面!!!
注解实现方法计时
1.自定义注解
1 2 3 4 5 6 7 8 9
|
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface TimeComsumingStatics { String methodName(); }
|
2.aop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Aspect @Component @EnableAspectJAutoProxy(proxyTargetClass = true) public class TimeComsumingAOP {
private static final Logger log = LoggerFactory.getLogger(TimeComsumingAOP.class);
@Value("${timeCusming:false}") public String openButton;
@Pointcut("@annotation(com.service.zl.vo.TimeComsumingStatics)") public void aspect() { }
@Around(value = "aspect() && @annotation(timeComsumingStatics)") public Object before(ProceedingJoinPoint proceedingJoinPoint,TimeComsumingStatics timeComsumingStatics) throws Throwable { if("true".equals(openButton)){ long actStartTime = System.currentTimeMillis(); Object proceed = proceedingJoinPoint.proceed(); long actEndTime = System.currentTimeMillis(); String timecusming = (actEndTime - actStartTime) + "毫秒"; log.info(timeComsumingStatics.methodName() + "耗时:" + timecusming); return proceed; }else { return proceedingJoinPoint.proceed(); } } }
|
3.application.properties
当timeCusming为true时开启接口耗时统计,false反之
4.注解使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import org.springframework.aop.framework.AopContext; import org.springframework.stereotype.Service;
@Service public class TestAopService {
public void methodA() { System.out.println("method A run"); ((TestAopService) AopContext.currentProxy()).methodB(); } @TimeComsumingStatics(methodName = "调用methodB") public void methodB() { System.out.println("method B run"); } }
|
5.结果
参考文献