spring-aop

1、动态代理

  动态代理是指,程序在整个运行过程中根本不存在目标类的代理类,目标的代理对象只是有代理生成工具(不是真实定义的类)在程序运行时有JVM根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。

1.1、JDK动态代理

  动态代理的实现方式常用的有两种:使用JDK的Proxy,与通过CGLIB生成代理。

  jdk的动态要求目标对象必须实现接口,这是java设计上的要求。从jdk1.3以来,java语言通过java.lang.reflect包提供三个类支持代理模式Proxy、Method和InovationHandler

1.2、CGLIB动态代理

  CGLIB(Code Generation Library)是一个开源项目。是一个强大的、高性能、高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。它广泛地被许多AOP的框架使用,例如SpringAOP。

  使用JDK的Proxy实现代理,要求目标类与代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。但对于无接口的类,要为其创建动态代理,就要使用CGLIB来实现。

  CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB生成动态代理,要求目标类必须能够被继承,即不能是final的类。

  CGLIB经常应用在框架中,例如Spring、Hibernate等。CGLIB的代理效率高于JDK。项目中直接使用动态代理的地方不多。一般都是用框架提供的功能。

2、AOP(Aspect Orient Programming)

  面向切面编程,基于动态代理,可以使用jdk,oglib两种代理方式。

  AOP就是动态代理的规范化,把动态代理的实现步骤、方式都定义好了,让开发人员用一种统一的方式,就用动态代理。

  Aspect:切面,给你的目标类增加的功能就是切面。切面一般都是非业务方法,是独立使用的。

  Orient:面向,对着

  Programming:编程

一、怎么理解面向切面编程?

1、需要在分析项目功能时,找出切面

2、合理地安排切面的执行时间(在目标方法钱,还是目标方法后)

3、合理地安排切面执行的位置,在哪个类,哪个方法增加增强功能

二、术语:

1)Aspect:切面,表示增强的功能,就是一堆代码,完成某个功能,非业务功能,常见的切面功能有日志、事务、统计数据、参数检查、权限验证。

2)JoinPoint:连接点,连接业务方法和切面的位置。就某类中的业务方法。

3)Pointcut:切入点,指多个连接点方法的集合,多个方法。

4)目标对象:给哪个类的方法增加功能,这个类就是目标对象。

5)Adivice:通知,通知表示切面功能执行的时间。

三、说一个切面有三个关键的要素:

1)切面的功能代码,切面干什么

2)切面的执行位置,使用Pointcut表示切面执行的位置

3)切面的执行的时间,使用Advice表示时间,在目标代码之前,还是目标代码之后

四、AOP的实现

aop是一个规范,是动态的一个规范化,一个标准。aop的实现框架:

1、spring:spring在内部实现了aop规范,能做aop的工作。但是在spring主要在事务处理时使用aop,我们项目开发中很少使用spring的aop实现。因为aop比较笨重。

2、Aspectj:一个开源的专门做aop的框架。spring框架中集成了aspectj框架,通过spring就能使用aspectj的功能。aspectj框架实现aop有两种方式:

1)使用xml的配置文件,配置全局事务。

2)使用注解,我们在项目中要做aop功能,一般都使用注解,aspectj有五个注解。

五、学习aspectj框架的使用

1、切面的执行时间,这个执行时间在规范中叫做Advice(通知,增强),在aspectj框架中使用注解表示的,也可以使用xml配置文件中的标签。

1)@Before

2)@AfterReturning

3)@Around

4)@AfterThrowing

5)@After

2、表示切面执行的位置,使用的是切入点语法表达式

AspectJ定义了专门的表达式用于指定切入点。表达式的原型是:

execution(modifiers-pattern? ret-type-pattern

     declaring-type-pattern? name-pattern(param-pattern)

     throws-pattern?)

 解释:

  • modifiers-pattern 访问权限类型
  • ret-type-pattern 返回值类型
  • name-pattern(param-pattern) 方法名(参数类型和参数个数)
  • throws-pattern 抛出异常类型
  • ?表示可选的部分
  • 以上表达式供4个部分(访问权限 方法返回值 方法声明(参数) 异常类型)

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显就是方法的签名。注意,表达式中的黑色文字表示可省略部分,各部分间用空格分开。在其中可以使用以下符号

符号 意义
* 0至多个任意字符
..

用在方法参数中,表示多个参数

用在包名后,表示当前包及其子包路径

+

用在类名后,表示当前类及其子类

用在接口后,表示当前接口及其实现类

举例:

1、execution(public * *(..)) 指定切入点:任意公共方法。

2、execution(* set*(..)) 指定切入点:任何一个以“set”开始的方法

3、execution(* com.xyz.service.*.*(...)) 指定切入点:定义在service包里的任意类的任意方法。

4、execution(* com.xyz.service..*.*(..)) 指定所有包下的service子包下所有类(接口)中所有方法为切入点

5、execution(* *.service.*.*(..)) 指定只有一级包下的service子包下所有类(接口)中所有方法为切入点

 

 

 

 

 

 

 

 

 

 

 

 

 

转载请注明出处:https://www.cnblogs.com/stu-jyj3621
原文地址:https://www.cnblogs.com/stu-jyj3621/p/14512844.html