AOP是指Aspect Oriented Programming 面向切面编程
AOP本质上就是动态代理 将一些常用功能从每个业务方法中剥离出来
写法如下
首先引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
然后定义一个切面
@Aspect
@Component
public class LoggingAspect {
// 在执行UserService的每个方法前执行:
@Before("execution(public * com.itranswarp.learnjava.service.UserService.*(..))")
public void doAccessCheck() {
System.err.println("[Before] do access check...");
}
// 在执行MailService的每个方法前后执行:
@Around("execution(public * com.itranswarp.learnjava.service.MailService.*(..))")
public Object doLogging(ProceedingJoinPoint pjp) throws Throwable {
System.err.println("[Around] start " + pjp.getSignature());
Object retVal = pjp.proceed();
System.err.println("[Around] done " + pjp.getSignature());
return retVal;
}
}
除了使用@Component
注解之外,还使用了@Aspect
注解,那么它被@Before
和@Around
注解的方法将被注入到后面字符串表示的位置执行
Before
表示UserService这个Bean的所有public方法之前
Around
表示MailService所有public方法的前后
我们需要在Configuration
上加一个@EnableAspectJAutoProxy
注解
拦截器类型:
@Before
:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;@After
:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;@AfterReturning
:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;@AfterThrowing
:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;@Around
:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。
在装配AOP时,最好使用注解来表明bean被装配了 比如使用@Transactional
来表明Bean在数据库事务中被调用
例子
定义一个注解或者使用已经存在的注解
@Target(METHOD)
@Retention(METHOD)
public @interface AspectMehod {
String value();
}
在需要切面的地方进行标注
@Component
public class UserService {
//监控register()方法性能;
@AspectMethod("register")
public User register(String email,String passwd,String name) {
...
}
}
编写切面方法
@Aspect
@Component
public class MetricAspect {
@Around("@annotation(method1)")
public Object metric(ProceedingJoinPoint joinPoint,AspectMethod method1) throws Throwable {
String name = method1.value();
long start = System.currentTimeMilllis();
try {
System.err.println("我在register之前");
return joinPint.proceed();
}finally {
long t = System.currentTimeMillis() - start;
System.err.println("[AspectMethod]" + name + ":" + t + "ms");
}
}
}