aspectj的五种通知方法
1.@Before前置通知,在方法执行之前执行
2.@After后置通知,在方法执行之后执行
3.@AfterReturning返回通知,在方法返回结果之后返回,可以访问方法的返回值,进行操作,例如写日志
4.@AfterThrowing异常通知,关联的方法若抛出异常,可以访问该异常,并进行操作
5.@Around环绕通知,围绕着方法进行执行,上述四种的功能都能实现,其必须有返回值
通知起效的前提是,被关联的方法和AOP切面已经在IOC容器中生成bean(声明式和注解都可以),同时需要在xml中声明<aop:aspectj-autoproxy />,表示声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面,具体的配置如下
<!-- 配置包扫描器 -->
<context:component-scan base-package="com.feng.part1"/>
<!--<span style="font-size:24px;"><span style="font-size:14px;">@aspectJ</span></span>注解起效-->
<aop:aspectj-autoproxy />
同时,本文中创建了一个切面类,而没采用在xml中定义的方式,配置通知类的代码如下
@Aspect
@Service
public class AspectTest {
@Before("execution(* com.feng.part1.*.*(..))")
public void before(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("method: " + methodName + " begins");
}
@After("execution(* com.feng.part1.*.*(..))")
public void After(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println("method: " + methodName + " ends");
}
@AfterReturning(value="execution(* com.feng.part1.*.*(..))",returning="result")
public void AfterReturning(JoinPoint joinPoint,Object result ){
String methodName=joinPoint.getSignature().getName();
System.out.println("method: "+methodName+" return result:"+result);
}
@AfterThrowing(value="execution(* com.feng.part1.*.*(..))",throwing="exception")
public void afterThrowing(JoinPoint joinPoint, exception){
String methodName=joinPoint.getSignature().getName();
System.out.println("method: "+methodName+"occurs exception:"+exception);
}
@Around(value = "execution(* com.feng.part1.*.*(..))")
public Object around(ProceedingJoinPoint pjp) {
String methodName = pjp.getSignature().getName();
Object result = null;
try {
// before
System.out.println("method: " + methodName + " begins");
// AfterReturning
result = pjp.proceed();
System.out.println("method: " + methodName + " return result:" + result);
} catch (Throwable e) {
// AfterThrowing
System.out.println("method: " + methodName + "occurs exception:" + e);
}
// After
System.out.println("method: " + methodName + " ends");
return result;
}
}
五种类型的通知本类中都已配置,其中最大的类上面必须加上@Aspect标签,表示这是一个切面类,同时,需要在具体的方法上配置切点,比如@Before("execution(* com.feng.part1.*.*(..))"),这个标签表示对com.feng.part1下的所有类的所有方法起效,这些方法在执行前,都会执行先执行before中的代码,同时,参数中的joinpoint表示切点,即这个方法。可以根据不同的通知,使用不同的属性。
返回通知和异常通知因为要调用额外的属性(result和exception),所以必须在参数和声明中预先配置result和exception,用以具体代码的执行。
环绕通知因其全面的功能,参数变为了 ProceedingJoinPoint,这个必须注意,且其必须设置返回值,其以一个try{}catch(){}代码块实现了上述四种的功能。
切面的添加可以使程序的一部分功能完全独立出来,例如日志,安全等,此种设计虽不符合java面向对象的编程思想,但实际的使用效果却非常好,代码的耦合度进一步降低,后期的维护成本大大降低,以本人看法还是一个不错的设计