Spring(三、Spring AOP)
来源:互联网 发布:js中大于等于怎么写 编辑:程序博客网 时间:2024/05/20 07:34
一、概念
AOP(Aspect Oriented Programming)概念:面向切面(方面)编程,扩展功能,不是通过修改源代码实现。
AOP采用横向抽取机制,取代了传统纵向集成体系重复性代码(性能监视、事务管理、安全检查、缓存)。
SpringAOP使用纯java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标植入增强代码。
AspectJ是一个基于java语言的AOP框架,Spring2.0开始,SpringAOP引入对Aspect的支持,AspectJ扩展了Java语言
,提供了一个专门的编译器,在编译时提供横向代码的植入。
二、原理
Spring的AOP的底层用到两种代理机制:
(1)JDK的动态代理:针对实现了接口的类产生代理。(2)Cglib的动态代理:针对没有实现接口的类产生代理。应用的是底层的字节码增强技术,生成当前类的子类对象。
三、操作术语
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.Advice(通知/增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field.Target(目标对象):代理的目标对象Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.spring 采用动态代理织入,而AspectJ采用编译期织入和类装在期织入Proxy(代理) :一个类被AOP 织入增强后,就产生一个结果代理类Aspect(切面): 是切入点和通知(引介)的结合
四、基于Aspecj的xml准备工作
1、使用AspectJ需要导入SpringAOP 和 AspectJ相关jar包。
2、创建spriong核心配置文件,导入aop的约束。
<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"></beans>
3、使用表达式配置切入点
1.切入点:实际增强的方法2.常用的表达式execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)(1)execution(* cn.itcast.aop.Book.add(..)) //对类中的ad地方法做增强。(2)execution(* cn.itcast.aop.Book.*(..))//对类中的所有方法做增强。(3)execution(* *.*(..)) //对所有类的所有方法做增强。(4) 匹配所有save开头的方法 execution(* save*(..))// savaXXX方法
五、Aspectj的AOP操作
package com.chen.aop;/** * 被增强类 * @author chen * */public class Book{ public void add() { System.out.println("book add...."); }}
package com.chen.aop;import org.aspectj.lang.ProceedingJoinPoint;/** * 增强类 * @author chen * */public class StrengthenBook { public void before1() { System.out.println("前置增强....."); }}
配置文件配置:
<!-- 1、配置对象 --><bean id="book" class="com.chen.aop.Book"></bean><bean id="stengthenBook" class="com.chen.aop.StrengthenBook"></bean><!-- 2、配置aop操作 --><aop:config> <!-- 2.1配置切入点 切入点:指定对哪个方法进行增强。 指定对book类的add()方法增强--> <aop:pointcut expression="execution(* com.chen.aop.Book.add(..))" id="pointcut1"/> <!-- 2.2配置切面 切面: 把增强用在具体方法的过程叫做切面--> <aop:aspect ref="stengthenBook"> <!-- 配置增强的类型 method:增强类中的哪个方法作为增强。 pointcut-ref:把增强用在哪个切入点上--> <aop:before method="before1" pointcut-ref="pointcut1"/> </aop:aspect></aop:config>
调用:
ApplicationContext context = new ClassPathXmlApplicationContext("aopbean.xml");Book book = (Book) context.getBean("book");book.add();
输出结果:
六、Aspectj的AOP其他操作
前置、后置、环绕通知:
增强类:
package com.chen.aop;import org.aspectj.lang.ProceedingJoinPoint;/** * 增强类 * @author chen * */public class StrengthenBook { public void before1() { System.out.println("前置增强....."); } public void after1() { System.out.println("后置增强...."); } //环绕通知,在方法之前和之后都执行 public void around1(ProceedingJoinPoint proceedingJoinPoint) { //方法之前执行 System.out.println("环绕,方法之前执行....."); //执行被增强的方法 try { proceedingJoinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } //方法之后执行 System.out.println("环绕,方法之后执行....."); }}
配置文件:
<!-- 1、配置对象 --> <bean id="book" class="com.chen.aop.Book"></bean> <bean id="stengthenBook" class="com.chen.aop.StrengthenBook"></bean> <!-- 2、配置aop操作 --> <aop:config> <!-- 2.1配置切入点 切入点:指定对哪个方法进行增强。 指定对book类的add()方法增强--> <aop:pointcut expression="execution(* com.chen.aop.Book.add(..))" id="pointcut1"/> <!-- 2.2配置切面 切面: 把增强用在具体方法的过程叫做切面--> <aop:aspect ref="stengthenBook"> <!-- 配置增强的类型 method:增强类中的哪个方法作为增强。 pointcut-ref:把增强用在哪个切入点上--> <aop:before method="before1" pointcut-ref="pointcut1"/> <aop:after method="after1" pointcut-ref="pointcut1"/> <!-- 环绕通知 --> <aop:around method="around1" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config>
调用:
public void testaop() { ApplicationContext context = new ClassPathXmlApplicationContext("aopbean.xml"); Book book = (Book) context.getBean("book"); book.add();}
输出:
七、基于Aspectj的注解aop操作
@AspectJ提供的不同的通知类型。
通知类型:* @Before :前置通知* @AfterReturing :后置通知* @Around :环绕通知* @After :最终通知* @AfterThrowing :异常抛出通知.
xml配置:
<?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"> <!--2、开启aop扫描操作 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!--1、创建对象 --> <bean id="book" class="com.chen.aop.annotation.Book"></bean> <bean id="stengthenBook" class="com.chen.aop.annotation.StrengthenBook"></bean></beans>
增强类:
package com.chen.aop.annotation;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;/** * 增强类 * @author chen * *///在增强类上添加Aspect注解@Aspectpublic class StrengthenBook { //在方法上面,使用注解完成增强的配置 @Before(value="execution(* com.chen.aop.annotation.Book.add(..))") public void before1() { System.out.println("annotation 前置增强....."); } @After(value="execution(* com.chen.aop.annotation.Book.add(..))") public void after1() { System.out.println("annotation 后置增强...."); } //环绕通知,在方法之前和之后都执行 @Around(value="execution(* com.chen.aop.annotation.Book.add(..))") public void around1(ProceedingJoinPoint proceedingJoinPoint) { //方法之前执行 System.out.println("annotation 环绕,方法之前执行....."); //执行被增强的方法 try { proceedingJoinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } //方法之后执行 System.out.println("annotation 环绕,方法之后执行....."); }}
调用输出:
ApplicationContext context = new ClassPathXmlApplicationContext("aopannotationbean.xml");Book book = (Book) context.getBean("book");book.add();
输出结果:
阅读全文
0 0
- Spring(三、Spring AOP)
- (三)Spring AOP
- Spring(三)AOP
- Spring旅程(三) AOP--Spring AOP容器基础
- 理解Spring AOP 原理(三)Spring AOP 源码分析
- Spring之三 AOP
- Spring框架 AOP(三)
- Spring(三) AOP
- Spring中AOP的实现 (三)
- 深入浅出Spring(三) AOP详解
- 深入浅出Spring(三) AOP详解
- Spring复习(三)AOP详解
- 浅谈Spring(三)AOP原理
- Spring笔记(三):Aop详解
- 技术总结 (三)--Spring aop
- spring学习(三)—AOP
- Spring框架内容整理(三):AOP
- Spring笔记(三):Aop详解
- 机器学习项目到底怎么做? 站在巨人的肩膀上!-----资料分享
- vs2017控制台出现中文乱码
- **系统调用**
- c语言实验—时间格式转换
- 《DOS命令一日通》第二章 使用计算机起步工作
- Spring(三、Spring AOP)
- php 字符串使用总结
- maven项目报错解决前提
- 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()
- jenkins启动方法-日常启动
- springmvc自定义视图解析器
- html文件和js脚本分离
- 四大组件--BroadcastReceiver
- 【bzoj 2763】T13 飞行路线(Spfa+分层图)