Aop编程就是面向编程的羝是切面,而切面是模块化横切关注点。

-切面:横切关注点,被模块化的特殊对象。

-通知:切面必须要完成的工作

-目标:被通知的对象

-代理:向目标对象应用通知之后创建的对象。

-连接点:程序执行的某个特定的位置。

-切点:相当于查询条件

其配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--加入自动扫描的包-->
<context:component-scan base-package="com.sevenhu.AOPTests"></context:component-scan>
<!--使AspesctJ的注解起作用-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

 声明切面的两种方式:

1.基于XML配置文件的方式:只需要在IOC容器中将切面声明为bean实例,当在Spring IOC容器中初始化AspectJ切面之后,Spring IOC容器会为那些与AspectJ切面相匹配的bean创建代理。

2.基于注解的方式:在AspectJ注解中,切面只是一个带有@Aspect注解的java类。

AspectJ支持5中类型的通知注解:

1.@Before:前置通知,在方法执行前执行

2.@After:后置通知,在方法执行后执行

3.@AfterReturning:返回通知,在方法返回结果之后执行

4.@AfterThrowing:异常通知,在方法抛出异常之后执行

5.@Around:环绕通知,围绕着方法执行。

上代码,首先建立一个bean实例:

package com.sevenhu.AOPTests;

import org.springframework.stereotype.Component;

/**
* Created by hu on 2016/4/1.
*/
@Component
public class Calculator {
//加
public int add(int a,int b){
return a+b;
}
//减
public int sub(int a,int b){
return a-b;
}
//乘
public int multiply(int a,int b){
return a*b;
}
//除
public double divide(int a,int b) throws Exception {
if(b==0){
throw new Exception();
}else{
return a/b;
}
}
}

  切面代码如下:

package com.sevenhu.AOPTests;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; import java.util.ArrayList;
import java.util.Arrays; /**
* Created by hu on 2016/4/1.
*/
@Aspect
@Component
public class AspectDemo {
//可以在通知方法中声明一个类型为JoinPoint的参数,然后就可以访问链接的细节,如方法名和参数值 //前置通知
@Before("execution(public int com.sevenhu.AOPTests.Calculator.*(int ,int ))")
public void beforeMethod(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
Object[] args=joinPoint.getArgs();
System.out.println("The method "+methodName+" begins with "+ Arrays.asList(args));
}
//后置通知:在连接点完成之后执行,即连接点返回结果或抛出异常的时候。
@After("execution(public int com.sevenhu.AOPTests.Calculator.*(int ,int ))")
public void afterMethod(JoinPoint joinPoint){
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" ends");
}
//返回通知:只在连接点返回结果的时候执行(即不抛出异常),并且还可以访问返回结果
@AfterReturning(pointcut = "execution(public int com.sevenhu.AOPTests.Calculator.*(int ,int ))",returning = "result")
public void afterMethodReturning(JoinPoint joinPoint,Object result){//必须在方法签名中添加一个同名的参数“result”,Spring会通过这个参数传递返回值
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" ends with a returning value "+result);
}
//异常通知:只有在连接点抛出异常的时候才会执行异常通知
@AfterThrowing(pointcut = "execution(public int com.sevenhu.AOPTests.Calculator.*(int ,int ))",throwing = "e")
public void afterMethodThrowing(JoinPoint joinPoint,Exception e){//必须在方法签名中添加一个同名的参数“e”,Spring会通过这个参数传递异常对象
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" has thrown a exception: "+e.getMessage());
}
//环绕通知:环绕通知是所有通知中功能最为强大的,能够全面控制连接点,甚至可以控制是否执行连接点,对于环绕通知,连接点参数是必须的
/*
* ProceedingJoinPoint是JoinPoint的子接口,允许控制何时执行,是否执行连接点
* 在环绕通知中需要明确调用ProceedingJoinPoint的proceed()方法来执行被代理的方法,如果忘记这样做就会导致通知被执行了,但是目标方法没有被执行。
* 注:环绕通知的方法需要返回目标方法执行之后的结果,即joinPoint.proceed();的返回值,否则 会出现空指针异常
* */
@Around("execution(public int com.sevenhu.AOPTests.Calculator.*(int ,int ))")
public void aroundMethod(ProceedingJoinPoint joinPoint) {
String methodName=joinPoint.getSignature().getName();
System.out.println("The method "+methodName+" begins");//相当于前置通知
try{
joinPoint.proceed();//执行连接点方法
}catch (Throwable e){
System.out.println("An Exception happened");//相当于异常通知
}
System.out.println("The method "+methodName+" ends");//相当于后置通知
}
}

  指定切面的优先级

在同一个连接点上可能不止一个切面,除非明确指定,否则它们的优先级是不确定的,切面的优先级可以通过实现Ordered接口 或@Order注解指定。

实现Order接口,getOrder()方法的返回值越小,优先级越高,常用的也就是使用注解的方式,所以具体方法如下:

@Aspect
@Order(0)
class Order1{
...
}
@Aspect
@Order(1)
class Order2{
...
}

重用切入点定义

在编写AspectJ切面时,可以直接在通知注解中书写切入点表达式,但是一个切入点表达式可能会在通知中重复出现。在AspectJ切面中,可以通过@PointCut注解将一个切入点声明成简单的方法,切入点的方法体通常是空的。其具体用法如下:

    @Pointcut("execution(* *.*(..)")
private void pointCut(){} @Before("pointCut()")
public void beforeMethod(){
System.out.println("doning sth...");
}

  

最新文章

  1. 【VLC-Android】vlc-android简例
  2. C++ Qt 框架静态编译 操作记录
  3. js 猜数字游戏
  4. [收藏]NET技术+25台服务器怎样支撑世界第54大网站
  5. 201. Bitwise AND of Numbers Range -- 连续整数按位与的和
  6. 最大似然估计(MLE)和最大后验概率(MAP)
  7. Android:Style和Theme
  8. [VirtualBox] Install Ubuntu 14.10 error 5 Input/output error
  9. 64位Window操作系统下,Orcal数据访问服务器端和客户端版本对应与通讯问题
  10. dedecms的安装以及为他配置虚拟主机
  11. bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色
  12. JUC
  13. java后台动态生成导出excel
  14. Unity设置播放模式下始终先执行指定的场景
  15. 863. All Nodes Distance K in Binary Tree 到制定节点距离为k的节点
  16. STL基础--迭代器和算法
  17. web漏洞详解及修复建议
  18. Apache中 RewriteCond 规则参数介绍
  19. Linux解决安装包无法找到问题Unable to locate package rar
  20. 【CF891E】Lust 生成函数

热门文章

  1. hbase基本命令
  2. JSON数据转换为字典型
  3. Android高级之Dalvik初识
  4. 行高不设单位的好处 line-height:1.8
  5. 实验 snort安装配置与规则编写
  6. 使用Aspose.Cell控件实现Excel高难度报表的生成(三)
  7. Sequential Read Ahead For SQL Server
  8. iOS:抽屉侧滑动画两种形式(1、UIView侧滑 2、ViewController侧滑)
  9. iOS:集成ijkplayer视频直播
  10. Medical image computing