一. 使用
- 目标方法
interface DivService { default int div(int a, int b) { return a / b; } } /** * 业务逻辑,目标方法 */ @Slf4j @Service class DivServiceImpl implements DivService { @Override public int div(int a, int b) { log.info("div目标方法被执行..."); return a / b; } }
- 定义切面
/** * LogAop */ @Component @Slf4j @Aspect class LogAspect { @Pointcut("execution(public int com.futao.springmvcdemo.test.aspect.DivService.*(..))") public void pointCut() { } @Before("pointCut()") public void before(JoinPoint point) { log.info("【{}】方法执行前@Before,参数列表:【{}】", point.getSignature().getName(), point.getArgs()); } /** * 无论目标方法是否成功,都会执行该方法 * * @param point */ @After(value = "pointCut()") public void after(JoinPoint point) { log.info("【{}】方法执行后@After", point.getSignature().getName()); } @AfterReturning(value = "pointCut()", returning = "result") public void afterReturning(JoinPoint point, Object result) { log.info("【{}】方法执行后正常返回@AfterReturning,返回值:【{}】", point.getSignature().getName(), result); } @AfterThrowing(value = "pointCut()", throwing = "e") public void afterThrowing(JoinPoint point, Exception e) { log.error("【{}】方法执行后发生异常,异常信息为【{}】", point.getSignature().getName(), e.getMessage()); } }
- 定义配置类,开启AspectJ动态代理
@ComponentScan("com.futao.springmvcdemo.test.aspect") @Configuration @EnableAspectJAutoProxy //开启AspectJ动态代理 class AspectJSpringConfig { } //或者 <aop:aspectj-autoproxy/>
- 测试
/** * @author futao * Created on 2019-04-17. */ public class AspectJTest { @Test public void test1() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AspectJSpringConfig.class); DivService divService = applicationContext.getBean(DivService.class); divService.div(1, 1); System.out.println(StringUtils.repeat("==", 50)); divService.div(1, 0); } }
结果
# 开发步骤以及注意事项
- 开发步骤
- 定义目标方法
- 定义切入点,切面等方法
- 将目标类与切面类都加入Spring容器中
- 将切面类加上@Aspect注解,表明这是一个切面类
- 开启Spring的注解式切面@ EnableAspectJAutoProxy
- 注意事项
- 目标类和切面类都需要加入到Spring容器中,交给Spring来管理。
- 通过new 目标类的方式生成的对象不会被切面拦截。