spring AOP编程--AspectJ注解方式
2016-06-29 19:06
666 查看
1. AOP 简介
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.
AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.
在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.
AOP 的好处:
---每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级
---业务模块更简洁, 只包含核心业务代码.
2. AOP的术语和图形表达
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
通知(Advice): 切面必须要完成的工作
目标(Target): 被通知的对象
代理(Proxy): 向目标对象应用通知之后创建的对象
连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置
切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
通知:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。无论是否抛出异常,都会执行。在后置通知中不能访问方法返回的结果
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知。
方式一、aspectj注解:
1、需要引入一个
2、ArithmeticCalculator.java
3、ArithmeticCalculatorImpl.java
4、LoggingAspect.java
这是一个日志切面类,该类首先是一个IoC中的bean,通过@Component将bean交个容器管理,然后@Aspect声明这是一个切面。
@Before是通知时机,表示在调用方法之前通知。 里面字符串格式为execution (访问修饰符 返回类型 包名.类名.方法名(参数类型...))。
beforeMethod是定一个的一个切面执行的方法,方法名可以任意指定。可以不带参数,也可以指定一个JoinPoint连接点的参数。
配置
aop:aspectj-autoproxy:使得@Aspect注解生效
测试代码:
输出结果
上面方法是用的前置通知。下面我们讲解一下后置通知、返回通知、异常通知和环绕通知
☆后置通知
后置通知无论方法是否抛出异常,都会执行。在后置通知中不能访问返回结果,因为可能会出现异常,就没有返回值
☆返回通知
当方法有异常时,不会执行返回通知,只有在方法正常执行结束才能够执行返回通知。在结果通知中用参数returning来指定接收返回结果对象的名称,直接传递给下面方法中对应的参数
☆异常通知
当方法有异常时,才会执行返回异常通知
【注意】:在指定异常类型时,只能捕获到该类型或子类型的异常。比如指定NullPointerException异常,就只能捕获空指针异常,所以,我们可以指定为异常的父类型。
☆环绕通知
环绕通知是一个比较强大,但相对复杂一点的通知,我们通常不使用
【注意】:环绕通知要求有一个返回值point.proceed()执行方法,并提供一个返回值
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.
AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.
在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.
AOP 的好处:
---每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级
---业务模块更简洁, 只包含核心业务代码.
2. AOP的术语和图形表达
切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
通知(Advice): 切面必须要完成的工作
目标(Target): 被通知的对象
代理(Proxy): 向目标对象应用通知之后创建的对象
连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置
切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
通知:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。无论是否抛出异常,都会执行。在后置通知中不能访问方法返回的结果
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知。
方式一、aspectj注解:
1、需要引入一个
2、ArithmeticCalculator.java
package com.proc; public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); }
3、ArithmeticCalculatorImpl.java
package com.proc; import org.springframework.stereotype.Component; @Component("arithmeticCalculator") public class ArithmeticCalculatorImpl implements ArithmeticCalculator{ public int add(int i, int j) { int result = i + j; return result; } public int sub(int i, int j) { int result = i - j; return result; } public int mul(int i, int j) { int result = i * j; return result; } public int div(int i, int j) { int result = i / j; return result; } }
4、LoggingAspect.java
package com.proc; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* *.*(int,int))") public void beforeMethod(JoinPoint point){ System.out.println("正在执行方法: "+point.getSignature().getName()); } }
这是一个日志切面类,该类首先是一个IoC中的bean,通过@Component将bean交个容器管理,然后@Aspect声明这是一个切面。
@Before是通知时机,表示在调用方法之前通知。 里面字符串格式为execution (访问修饰符 返回类型 包名.类名.方法名(参数类型...))。
beforeMethod是定一个的一个切面执行的方法,方法名可以任意指定。可以不带参数,也可以指定一个JoinPoint连接点的参数。
配置
<context:component-scan base-package="com.proc" /> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
aop:aspectj-autoproxy:使得@Aspect注解生效
测试代码:
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); ArithmeticCalculator calc=(ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); System.out.println(calc.add(3, 5)); System.out.println(calc.sub(3, 5)); System.out.println(calc.mul(6, 2)); System.out.println(calc.div(6, 2));
输出结果
正在执行方法add 8 正在执行方法sub -2 正在执行方法mul 12 正在执行方法div 3
上面方法是用的前置通知。下面我们讲解一下后置通知、返回通知、异常通知和环绕通知
☆后置通知
后置通知无论方法是否抛出异常,都会执行。在后置通知中不能访问返回结果,因为可能会出现异常,就没有返回值
@After("execution(* *.*(int,int))") public void afterMethod(JoinPoint point){ System.out.println("方法执行结束: "+point.getSignature().getName()); }
☆返回通知
当方法有异常时,不会执行返回通知,只有在方法正常执行结束才能够执行返回通知。在结果通知中用参数returning来指定接收返回结果对象的名称,直接传递给下面方法中对应的参数
@AfterReturning(value="execution(* *.*(int,int))",returning="retVal") public void afterReturningMethod(JoinPoint point,Object retVal){ System.out.println("方法: "+point.getSignature().getName()+"执行结果为:"+retVal); }
☆异常通知
当方法有异常时,才会执行返回异常通知
@AfterThrowing(value="execution(* *.*(int,int))",throwing="ex") public void afterThrowingMethod(JoinPoint point,Exception ex){ System.out.println("执行方法: "+point.getSignature().getName()+"出现了异常:"+ex.getMessage()); }
【注意】:在指定异常类型时,只能捕获到该类型或子类型的异常。比如指定NullPointerException异常,就只能捕获空指针异常,所以,我们可以指定为异常的父类型。
☆环绕通知
环绕通知是一个比较强大,但相对复杂一点的通知,我们通常不使用
@Around("execution(* *.*(int,int))") public Object aroundMethod(ProceedingJoinPoint point){ System.out.println("环绕通知: "+point.getSignature().getName()); Object result=null; //这里相当于前置通知 try { //执行方法 result= point.proceed(); //这里相当于结果通知 } catch (Throwable e) { //这里相当于异常通知 e.printStackTrace(); } //这里相当于后置通知 System.out.println("环绕通知: "+point.getSignature().getName()); return result; }
【注意】:环绕通知要求有一个返回值point.proceed()执行方法,并提供一个返回值
相关文章推荐
- asp.net mvc 部分视图加载区别
- ASP.NET Web API 接口执行时间监控
- 控制ASP.NET Web API 调用频率
- asp js获取服务器控件的简单方法
- Asp.Net MVC 模型(使用Entity Framework创建模型类)
- ASP.NET MVC 域名泛解析设置
- spring AspectJ的Execution表达式
- 七天学会ASP.NET MVC (三)——ASP.Net MVC 数据处理
- [ASP.NET]利用DataTable对DropDownList进行数据绑定
- casperjs 安装
- Asp.Net处理URL空格变%20问题
- c#/asp.net 对一个内容字符串提取字符串的图片,并且转换为UBB
- ASP.NET MVC企业级实战目录
- ASPNET树形级联
- 开源Asp.Net Core小型社区系统
- asp.net服务器控件的生命周期
- GRASP----(职责分配原则)
- asp.net mvc中应用Grid++ Report (基本应用示例)
- Infragistics.NetAdvantage.Ultimate.2011 ASP.NET Product Changes
- ASP.NET MVC 静态资源打包和压缩问题小记