spring-aop(一)基础知识
2016-09-27 00:00
363 查看
通知:切面的工作称为通知,通知定义了切面是什么以及何时用
连接点:
连接点是一个应用执行过程中能够插入一个切面的点。
连接点可以是调用方法时、抛出异常时、甚至修改字段时、
切面代码可以利用这些点插入到应用的正规流程中
程序执行过程中能够应用通知的所有点
切点:
如果通知定义了“什么”和“何时用”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。
通常使用明确的类或者方法来指定这些切点。
作用:定义通知被应用的位置(在哪些连接点)
切面:通知和切点的结合(何时,何处 完成工作)
引入:
织入:
spring 提供4中类型的AOP支持 :1.基于代理的经典SpringAOP;2.纯POJO切面;3.@AspectJ注解驱动的切面;4.注入式AspectJ切面(适用于Spring各版本 )
spirng在运行时通知对象:代理拦截方法,当需要用到时才给到被代理的bean;
Spring只支持方法级别的连接点:如果方法拦截不能满足需求可以用Aspect来补充Spring AOP功能
4.2通过切点来选择连接点:只有execution指示器是编写切点定义的主要指示器。其他事限制所匹配的切点。
指示器:arg() ; @args(); execution(); this(); target; @target; within(); @within(); @annotation;
编写切点:execution(* concert.Performance.perform(..)) && within(concert.*) --执行concert包下的Performacnce类中的perform方法,但限定只匹配concert包。&&还可以有 “||”;“!”
在切点中选择bean:使用bean的id或者bean的名称:execution(* concert.Performance.perform(..)) and bean('woodstock') --执行Performance的perform()方法是应用通知,但限定bean的ID为woodstock
4.3使用注解创建切面:
4.3.1:定义切面,观众对于一场演出来说不是最核心的,所以观众定义为演出的一个切面,应用于演出
Audience 只是一个java类,只不过它公国注解表明会作为切面使用而已;
装配为Spring中的Bean:
启动自动代理功能:
也可以用xml来装配bean :<aop:aspectj-autoproxy>
这样AspectJ自动代理会为使用@Aspect注解的bean创建一个代理 “切面基于代理”
4.3.2 创建环绕通知
通知中通过ProceedingJonPoint 对象来调用被通知的方法
4.3.3 处理通知中的参数
用 @Pointcut注解 命名切点 execution(* soundsystem.CompactDisc.playTrack(int)) && args(trackNumber) 并用@Before前置通知,args(trackNumber)完成了 从命名切点到通知方法的参数转移。
4.3.4 通过注解引入新功能
连接点:
连接点是一个应用执行过程中能够插入一个切面的点。
连接点可以是调用方法时、抛出异常时、甚至修改字段时、
切面代码可以利用这些点插入到应用的正规流程中
程序执行过程中能够应用通知的所有点
切点:
如果通知定义了“什么”和“何时用”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。
通常使用明确的类或者方法来指定这些切点。
作用:定义通知被应用的位置(在哪些连接点)
切面:通知和切点的结合(何时,何处 完成工作)
引入:
织入:
spring 提供4中类型的AOP支持 :1.基于代理的经典SpringAOP;2.纯POJO切面;3.@AspectJ注解驱动的切面;4.注入式AspectJ切面(适用于Spring各版本 )
spirng在运行时通知对象:代理拦截方法,当需要用到时才给到被代理的bean;
Spring只支持方法级别的连接点:如果方法拦截不能满足需求可以用Aspect来补充Spring AOP功能
4.2通过切点来选择连接点:只有execution指示器是编写切点定义的主要指示器。其他事限制所匹配的切点。
指示器:arg() ; @args(); execution(); this(); target; @target; within(); @within(); @annotation;
编写切点:execution(* concert.Performance.perform(..)) && within(concert.*) --执行concert包下的Performacnce类中的perform方法,但限定只匹配concert包。&&还可以有 “||”;“!”
在切点中选择bean:使用bean的id或者bean的名称:execution(* concert.Performance.perform(..)) and bean('woodstock') --执行Performance的perform()方法是应用通知,但限定bean的ID为woodstock
4.3使用注解创建切面:
4.3.1:定义切面,观众对于一场演出来说不是最核心的,所以观众定义为演出的一个切面,应用于演出
@Aspect public class Audience{ @Pointcut("execution(** concert.Performance.perform(..))") public void performance(){ @Before("performance()") //前置通知 public void silenceCellphones(){ Sysotem.out.println("Silencing cell phones"); } @Before("performance()") //前置通知 public void takeSeats(){ Sysotem.out.println("Takeing seats"); } @AfterReturning("performance()") //后置通知 public void applause(){ Sysotem.out.println("Clap Clap Clap!!!"); } @AfterThrowing("performance()") //通知方法会将目标方法封装起来。 public void demandRefund(){ Sysotem.out.println("Demanding a refund"); } } }
Audience 只是一个java类,只不过它公国注解表明会作为切面使用而已;
装配为Spring中的Bean:
@Bean public Audience audience(){ return new Audience(); }
启动自动代理功能:
package concert @Configuration @EnableAspectJAutoProxy //启用AspectJ自动代理 @ComponentScan public class ConcertConfig{ @Bean public Audience audience(){ //声明Audience bean return new Audience(); } }
也可以用xml来装配bean :<aop:aspectj-autoproxy>
这样AspectJ自动代理会为使用@Aspect注解的bean创建一个代理 “切面基于代理”
4.3.2 创建环绕通知
@Aspect public class Audience{ @Pointcut("execution(** concert.Performance.perform(..))") //定义命名的切点 public void performance(){} @Around("performance()") public void watchPerformance(ProceedingJonPoint jp){ try{ Sysotem.out.println("Silencing cell phones"); Sysotem.out.println("Takeing seats"); jp.proceed(); Sysotem.out.println("Clap Clap Clap!!!"); } catch(Throwable e){ Sysotem.out.println("Demanding a refund"); } } }
通知中通过ProceedingJonPoint 对象来调用被通知的方法
4.3.3 处理通知中的参数
@Aspect public class TrackCounterImpl implements ITrackCounter { private Map<Integer, Integer>trackCounts = new HashMap<Integer, Integer>(); @Pointcut("execution(* soundsystem.CompactDisc.playTrack(int))" + "&& args(trackNumber)") //"&& args(trackNumber)")限定传递给playTTrack()的int类型参数也会传递到通知中 public void trackPlayed(int trackNumber){} @Before("trackPlayed(trackNumber)") public void countTrack(int trackNumber){ int currentCount = getPlayCount(trackNumber); trackCounts.put(trackNumber, currentCount + 1); } public int getPlayCount(int trackNumber){ return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0; } }
用 @Pointcut注解 命名切点 execution(* soundsystem.CompactDisc.playTrack(int)) && args(trackNumber) 并用@Before前置通知,args(trackNumber)完成了 从命名切点到通知方法的参数转移。
4.3.4 通过注解引入新功能
相关文章推荐
- [Java]Spring AOP基础知识-动态代理
- Spring AOP基础知识学习——XML配置
- Spring AOP基础知识
- Spring基础知识和AOP使用注意
- Spring AOP 基础知识2
- Spring AOP的一些基础知识
- spring基础知识3:aop
- Spring-AOP基础知识
- Spring AOP基础知识1
- Spring基础知识-IOC、DI、AOP
- spring知识五------AOP基础
- 【Spring in Action】Spring的AOP基础知识及切面运用
- Spring AOP基础知识
- Spring基础知识(5)-AOP
- spring aop基础知识
- 学习spring应掌握的Java基础知识
- 学习Spring必学的Java基础知识(转)
- 【第四章】 资源 之 4.1 基础知识 ——跟我学spring3
- 学习Spring必学的Java基础知识(6)----ThreadLocal
- 学习Spring必学的Java基础知识(2)----动态代理