@AspectJ的详细用法 
在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:

一些常见的切入点的例子 
execution(public * * (. .)) 任意公共方法被执行时,执行切入点函数。 
execution( * set* (. .)) 任何以一个“set”开始的方法被执行时,执行切入点函数。 
execution( * com.demo.service.AccountService.* (. .)) 当接口AccountService 中的任意方法被执行时,执行切入点函数。 
execution( * com.demo.service.. (. .)) 当service 包中的任意方法被执行时,执行切入点函数。 

within(com.demo.service.) 在service 包里的任意连接点。 

within(com.demo.service. .) 在service 包或子包的任意连接点。 

this(com.demo.service.AccountService) 实现了AccountService 接口的代理对象的任意连接点。 
target(com.demo.service.AccountService) 实现了AccountService 接口的目标对象的任意连接点。 
args(java.io.Serializable) 任何一个只接受一个参数,且在运行时传入参数实现了 Serializable 接口的连接点 
增强的方式: 
@Before:方法前执行 
@AfterReturning:运行方法后执行 
@AfterThrowing:Throw后执行 
@After:无论方法以何种方式结束,都会执行(类似于finally) 
@Around:环绕执行

添加 PointCut

该pointcut用来拦截test包下的所有类中的所有方法。

package com.aop.test1;

import org.aspectj.lang.annotation.Pointcut;

public class PointCuts {
	@Pointcut(value = "within(com.aop.test1.*)")
	public void aopDemo() {

	}
}
添加Aspect

该类中的advice将会用到上面的pointcut,使用方法请看各个advice的value属性。

package com.aop.test1;

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.springframework.stereotype.Component;

@Component
@Aspect
public class Aspect1 {

	@Before(value = "test.PointCuts.aopDemo()")
	public void before(JoinPoint joinPoint) {
		System.out.println("[Aspect1] before advise");
	}

	@Around(value = "test.PointCuts.aopDemo()")
	public void around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("[Aspect1] around advise 1");
		pjp.proceed();
		System.out.println("[Aspect1] around advise2");
	}

	@AfterReturning(value = "test.PointCuts.aopDemo()")
	public void afterReturning(JoinPoint joinPoint) {
		System.out.println("[Aspect1] afterReturning advise");
	}

	@AfterThrowing(value = "test.PointCuts.aopDemo()")
	public void afterThrowing(JoinPoint joinPoint) {
		System.out.println("[Aspect1] afterThrowing advise");
	}

	@After(value = "test.PointCuts.aopDemo()")
	public void after(JoinPoint joinPoint) {
		System.out.println("[Aspect1] after advise");
	}
}
添加测试用Controller

添加一个用于测试的controller,这个controller中只有一个方法,但是它会根据参数值的不同,会作出不同的处理:一种是正常返回一个对象,一种是抛出异常(因为我们要测试@AfterThrowing这个advice)

package com.aop.test1;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/aop")
public class AopTestController {

	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = "/test", method = RequestMethod.GET)
	public Result test(@RequestParam boolean throwException) {
		// case 1
		if (throwException) {
			System.out.println("throw an exception");
			throw new RuntimeException("mock a server exception");
		}

		// case 2
		System.out.println("test OK");
		return new Result() {
			{
				this.setId(111);
				this.setName("mock a Result");
			}
		};
	}

	public static class Result {
		private int id;
		private String name;

		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
	}
}

我们会看到输出的结果是:

[Aspect1] around advise 1
[Aspect1] before advisetest OK
[Aspect1] around advise2
[Aspect1] after advise
[Aspect1] afterReturning advise

异常情况,我们会看到输出的结果是:

[Aspect1] around advise 1
[Aspect1] before advise
throw an exception
[Aspect1] after advise
[Aspect1] afterThrowing advise


正常情况: 
one-ok




异常情况: 
one-exception


@Component
@Aspect
public class CacheAspect {
    @Around("execution(public * *(..)) and @annotation(checkCache)")
    public Object get(ProceedingJoinPoint jp, CheckCache checkCache) throws Throwable {
    
    }
    @AfterReturning(pointcut = "@annotation(evictCache)", returning = "retval")
    public void remove(JoinPoint jp, EvictCache evictCache, Object retval) {
    
    }
}