实战使用
测试直接在开源框架,jeesite上进行
导入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
切面类:
package com.jeesite.modules.test.service;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 java.util.Arrays;//表明当前类为切面类@Aspect//将当前类放到Spring容器中@Componentpublic class AopTest {private static final Logger log = LoggerFactory.getLogger(AopTest.class);/*后置切入测试*///设置要切入的点//PointCut表达式@Pointcut("execution(public * com.jeesite.modules.sys.service.support.LogServiceSupport.insertLog(..))")private void newController1() {//PointCut签名方法,没有实际作用,只是用来标记一个Pointcut,作为切入点的标记}//@After表示在目标方法之后执行下面的方法(afterController())@After("newController1()")private void afterController(JoinPoint joinPoint) {Object[] args = joinPoint.getArgs();//打印被切方法形参log.info("insertLog:{}",Arrays.toString(args));}@Pointcut("execution(public * com.jeesite.modules.sys.web.user.UserController.info(..))")private void newController2() {}/*环绕切入测试*/@Around(value = "newController2()", argNames = "pjp")private String aroundController(ProceedingJoinPoint pjp) {// try {// //proceed()方法表示执行目标方法,如果不使用proceed(),就不会执行目标方法,只会执行此方法(aroundController()),可以实现目标方法被替换的效果// pjp.proceed();// } catch (Throwable e) {// e.printStackTrace();// }// User user = new User();// user.setUserName("ahzoo");// try {//使用proceed(),可以用数组形式,传递参数给目标方法,参数个数需与目标方法形参个数一致// pjp.proceed(new Object[]{user,"",null});// } catch (Throwable e) {// e.printStackTrace();// }Object[] args = pjp.getArgs();//打印被切方法形参log.info("info:{}",Arrays.toString(args));//替换目标方法return语句return "modules/sys/user/userSelect";}/*批量(前置)切入测试*/@Pointcut("execution(public String com.jeesite.modules.sys.web.LoginController.switchSkin(..))")public void newController12() {}//可以一次对多个切面进行切入@Before("newController12() || newController1()")public void beforeController1(JoinPoint joinPoint) {log.info("测试切入");}}

目标被切方法1(后置切入):
@Transactional(readOnly=false)//, propagation=Propagation.NOT_SUPPORTED)public void insertLog(Log entity) {dao.insert(entity);}
测试图:

目标被切方法2(环绕切入):
@RequiresPermissions("user")@RequestMapping(value = "info")public String info(User user, String op, Model model) {if (StringUtils.isBlank(op)){op = "base";}model.addAttribute("op", op);model.addAttribute("user", UserUtils.getUser());//为了显示环绕通知效果,加了这段打印代码logger.info("userInfo:{}","here");return "modules/sys/user/userInfo";}
测试图:

批量切入测试(前置切入):
表达式优化
优化前
@Before("execution(* aa.*.*(..))")public void begin() {System.out.println("开始事务");}@After("execution(* aa.*.*(..))")public void close() {System.out.println("关闭事务");}
优化后:
优化后就只需要写一次切面表达式就行了
@Pointcut("execution(* aa.*.*(..))")public void pt() {}@Before("pt()")public void begin() {System.out.println("开始事务");}@After("pt()")public void close() {System.out.println("关闭事务");}
后记
实测无法切入 子类重写父类的方法,及 通过this调用的方法
