一、五种通知类型
注解 | 说明 |
---|
Before Advice | 前置通知,目标方法执行运行 |
After Returning Advice | 返回后通知,目标方法返回数据后执行 |
After Throwing Advice | 异常通知,目标方法抛出异常后执行 |
After Advice | 后置通知,目标方法运行后执行 |
Around Advice | 环绕通知,最强大的通知,自定义通知执行时机,可决定目标方法是否运行 |
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.learn..*Service.*(..))"></aop:pointcut>
<aop:aspect ref="methodAspect">
<aop:before method="printExecutionTime" pointcut-ref="pointcut"/>
<aop:after method="doAfter" pointcut-ref="pointcut"/>
<aop:after-returning method="doAfterReturning" returning="ret" pointcut-ref="pointcut"/>
<aop:after-throwing method="doAfterThrowing" throwing="th" pointcut-ref="pointcut"></aop:after-throwing>
</aop:aspect>
</aop:config>
package com.learn.spring.aop.aspect;
import org.aspectj.lang.JoinPoint;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MethodAspect {
public void printExecutionTime(JoinPoint joinPoint){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String now = sdf.format(new Date());
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
System.out.println("------>" + now + ":" + className + "." + methodName);
Object[] args = joinPoint.getArgs();
System.out.println("----->参数个数:" + args.length);
for (Object arg : args){
System.out.println("----->参数:" + arg);
}
}
public void doAfter(JoinPoint joinPoint){
System.out.println("<-----触发后置通知");
}
public void doAfterThrowing(JoinPoint joinPoint, Throwable th){
System.out.println("<-------异常通知:" + th.getMessage());
}
public void doAfterReturning(JoinPoint joinPoint, Object ret){
System.out.println("<----返回后通知:" + ret);
}
}
二、环绕通知
1.利用AOP进行方法性能筛查
<bean id="userDao" class="com.learn.spring.aop.dao.UserDao"/>
<bean id="employeeDao" class="com.learn.spring.aop.dao.EmployeeDao"/>
<bean id="userService" class="com.learn.spring.aop.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="employeeService" class="com.learn.spring.aop.service.EmployeeService">
<property name="employeeDao" ref="employeeDao"/>
</bean>
<bean id="methodChecker" class="com.learn.spring.aop.aspect.MethodChecker"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.learn..*.*(..))"></aop:pointcut>
<aop:aspect ref="methodChecker">
<aop:around method="check" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
package com.learn.spring.aop.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MethodChecker {
public Object check(ProceedingJoinPoint pjp) throws Throwable {
try {
long startTime = new Date().getTime();
Object ret = pjp.proceed();
long endTime = new Date().getTime();
long duration = endTime - startTime;
if (duration >= 1000){
String className = pjp.getTarget().getClass().getName();
String methodName = pjp.getSignature().getName();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String now = sdf.format(new Date());
System.out.println("========" + now + ":" + className + "." + methodName + "(" + duration + "ms)===========");
}
return ret;
} catch (Throwable e) {
throw e;
}
}
}
三、特殊的“通知”- 引介增强
1.什么是引介增强?
- 引介增强(IntroductionInterceptor)是对类的增加,而非方法
- 引介增强允许在运行时为目标类增加新属性或方法
- 引介增强允许在运行时改变类的行为,让类随运行环境动态变更