在使用AOP的时候遇到了一些问题,特此记录一下
首先写一个常用的AOP切片
切片类AopLog
package com.mantis.aop.aspect; import com.fasterxml.jackson.databind.ObjectMapper; import com.mantis.aop.common.util.DataUtil; import eu.bitwalker.useragentutils.UserAgent; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.stream.Collectors; /** * @Description:执行顺序 正常顺序 Around Before Method.invoke Around After AfterReturning * 异常顺序 Around Before Method.invoke After AfterThrowing * @author: wei.wang * @since: 2020/4/4 13:47 * @history: 1.2020/4/4 created by wei.wang */ @Aspect @Component public class AopLog { private static Logger logger = LoggerFactory.getLogger(AopLog.class); /** * 定义切点,切点为com.smec.fin.controller包和子包里任意方法的执行和service层所有方法的执行 */ @Pointcut("execution(public * com.mantis.aop.controller..*.*(..))") public void log() { // 定义切点 } /** * 定义切点,切点为com.smec.fin.controller包和子包里任意方法的执行和service层所有方法的执行 */ @Pointcut("exe<strong style="color:transparent">本文来源gaodai#ma#com搞@@代~&码*网/</strong>cution(public * com.mantis.aop.service.impl..*.*(..))") public void log2() { // 定义切点 } /** * 环绕通知 * * @param point * @return * @throws Throwable */ @Around("log2()") public Object aroundLog(ProceedingJoinPoint point) throws Throwable { logger.info("开始执行环绕操作"); Object result = point.proceed(); logger.info("执行环绕操作结束,返回值:{}", result); return result; } }
服务类AopServiceImpl
package com.mantis.aop.service.impl; import com.mantis.aop.service.AopService; import org.springframework.aop.framework.AopContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Description: * @author: wei.wang * @since: 2020/10/24 12:45 * @history: 1.2020/10/24 created by wei.wang */ @Service public class AopServiceImpl implements AopService { @Override public void testAop(String str) { System.out.println("com.mantis.aop.service.AopService.AopServiceImpl.testAop" + str); this.testAop2("testFinalMethod"); } @Override public void testAop2(String str) { //this.testFinalMethod("testFinalMethod"); System.out.println("com.mantis.aop.service.AopService.AopServiceImpl." + str); } public final void testFinalMethod(String str) { System.out.println("com.mantis.aop.service.AopService.AopServiceImpl.testFinalMethod" + str); } public void testFinalMethod2(String str) { System.out.println("com.mantis.aop.service.AopService.AopServiceImpl.testFinalMethod" + str); } }
1.同方法运行问题
在使用AOP时我们发现存在同类中调用时切点失效问题,在执行时我们发现只执行了testAop的切点,testAop2的切点没有执行,这是因为经过AOP代理后的对象都已经不是原来的对象了,而是加入了增强方法的代理对象,使用代理对象调用时可以执行增强方法,但是这里是使用this调用的,也就是AopServiceImpl,因为不是代理对象就没有增强方法。
2020-10-24 13:31:06.261 INFO 13344 --- [nio-9000-exec-1] com.mantis.aop.controller.AopController : 方法开始执行 2020-10-24 13:31:06.264 INFO 13344 --- [nio-9000-exec-1] com.mantis.aop.aspect.AopLog : 开始执行环绕操作 com.mantis.aop.service.AopService.AopServiceImpl.testAoptest2 com.mantis.aop.service.AopService.AopServiceImpl.testFinalMethod 2020-10-24 13:31:06.274 INFO 13344 --- [nio-9000-exec-1] com.mantis.aop.aspect.AopLog : 执行环绕操作结束,返回值:null