面向切面编程AOP:基于注解的配置
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...");
}
面向切面编程AOP:基于注解的配置的更多相关文章
- AOP面向切面编程(使用注解和使用配置文件)
Aop(面向切面编程) 使用注解的方式: 加入相应的jar包: com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspe ...
- Spring框架学习笔记(2)——面向切面编程AOP
介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
- Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)
在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...
- Spring学习手札(二)面向切面编程AOP
AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...
- Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
- Spring之控制反转——IoC、面向切面编程——AOP
控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...
- 设计模式之面向切面编程AOP
动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...
- 【串线篇】面向切面编程AOP
面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...
- [译]如何在ASP.NET Core中实现面向切面编程(AOP)
原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...
随机推荐
- C# .Net实现URL绝对路径和相对路径之间互相转换
网站制作开发中,URL的绝对路径和相对路径之间互相转换,是经常需要用到的.以下是在C#.Net下一种实现二者互相转化的方法: [DllImport("shlwapi.dll", C ...
- MVC3中几个小知识点
1.ViewBag.Name~ViewBag.name等价,即不区分大小写.在此小心,下次见到不要奇怪,不过最好还是写成一样的比较好. 2.JS字符串不允许有换行符,\'等字符,需提前处理.
- isset和empty比较
PHP的isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在 ...
- ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click 'Restart'
ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click ...
- Linux Socket过程详细解释(包括三次握手建立连接,四次握手断开连接)
我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web 服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠s ...
- 20145211 《Java程序设计》第7周学习总结——沧海横流
教材学习内容总结 Lambda Arrays的sort()方法可以用来排序,在使用sort()时,需要操作java.util.Comparator来进行说明,这样一来,语法就显得有些冗长.在JDK8中 ...
- 1058 N的阶乘的长度
1058 N的阶乘的长度 基准时间限制:1 秒 空间限制:131072 KB 输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. Input 输入N(1 <= N <= ...
- 1011 最大公约数GCD
1011 最大公约数GCD 基准时间限制:1 秒 空间限制:131072 KB 输入2个正整数A,B,求A与B的最大公约数. Input 2个数A,B,中间用空格隔开.(1<= A,B < ...
- Candies---hdu3159(spfa+差分约束)
题目链接:http://poj.org/problem?id=3159 题意:有n个小孩,m个关系格式是A B C 表示小孩 B 的糖果数最多比小孩A多C个,相当于B-A<=C; 有m个这样的关 ...
- SQL Server 2008 R2[ALTER]列属性修改
1:向表中添加字段 Alter table [表名] add [列名] 类型 2: 删除字段 Alter table [表名] drop column [列名] 3: 修改表中字段类型 (可以修 ...