简单AOP
Service类
import org.springframework.stereotype.Component; // 代理目标类 @Component public class BusinessService { public void executeBuss() { System.out.println("执行业务处理..."); } public int add(int a, int b) { System.out.println("执行add业务处理..."); return a+b; } }
切面类
import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * 切面配置 */ @Component @Aspect public class AspectConfig { @Pointcut("execution(* com.daimeng.test..*(..))") private void pointCut() { } /** * 环绕通知 */ @Around("pointCut()") public Object testAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("@Around通知---->执行业务前打印日志..."); Object obj = joinPoint.proceed(); System.out.println("@Around通知---->执行业务后打印日志..."); return obj; } @Before("pointCut()") public void before(JoinPoint join){ //获取方法名 String mathName=join.getSignature().getName(); //获取参数列表 List<Object> args = Arrays.asList(join.getArgs()); System.out.println("@Before通知---->before 方法名是:"+mathName+"\t参数列表是:"+args); } @After("pointCut()") public void after(JoinPoint joinPoint){ System.out.println("@After通知---->after...."); } @AfterReturning(value = "pointCut()", returning = "result") public void logReturn(JoinPoint joinPoint, Object result) { System.out.println("@AfterReturning通知---->after...." + result); } @AfterThrowing(value = "pointCut()", throwing = "exception") public void logException(JoinPoint joinPoint, Exception exception) { System.out.println("@AfterThrowing通知---->after....异常信息: "+ exception.getMessage()); } }
注册容器
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @ComponentScan(basePackages = "com.aop.test") @EnableAspectJAutoProxy public class BeansConfig { }
main方法
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestMain { public static void main(String[] args) { // 通过Java配置来实例化Spring容器 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeansConfig.class); // 在Spring容器中获取Bean对象 BusinessService businessService = context.getBean(BusinessService.class); businessService.executeBuss(); businessService.add(10, 20); // 销毁该容器 context.destroy(); } }
结果
@Around通知---->执行业务前打印日志... @Before通知---->before 方法名是:executeBuss参数列表是:[] 执行业务处理... @Around通知---->执行业务后打印日志... @After通知---->after.... @AfterReturning通知---->after....null @Around通知---->执行业务前打印日志... @Before通知---->before 方法名是:add参数列表是:[10, 20] 执行add业务处理... @Around通知---->执行业务后打印日志... @After通知---->after.... @AfterReturning通知---->after....30
由此可知各个切点的现后顺序
Around(前置) -> Before -> Around(后置) -> After -> AfterReturning
Around(前置) -> Before -> Around(后置) -> After -> AfterReturning