AOP编程(aspect oriented program)面向切面编程

A) 静态代理设计模式




spring boot 两个服务互相注入 spring两个service事务_字符串


spring boot 两个服务互相注入 spring两个service事务_设计模式_02


spring boot 两个服务互相注入 spring两个service事务_代理类_03


现实生活中的场景:


spring boot 两个服务互相注入 spring两个service事务_设计模式_04


概念:通过代理类为原始类增加额外功能。

好处:避免原始类因为额外功能频繁被修改,从而使代码更加利于维护。

名词解释:

1. 原始类或者目标类(target):那些只负责核心功能,没有加入额外功能的类。纯净的Service。

2. 原始功能,原始方法:原始类中的方法,没有加入额外功能的方法。

3. 额外功能:可有可无的,附加的功能。

代理类本质 = 原始类 + 额外功能 + 实现原始类的相同接口

静态代理设计模式的问题:

1. 代理类的数量过多,不利于项目管理。

2. 额外功能的代码冗余。

3. 替换代理的额外功能太麻烦。

B) Spring的动态代理设计模式

概念:通过代理类为原始类增加额外功能。

好处:利于原始类维护。

动态代理中需要引入额外的两个第三方依赖jar包:

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

1. 开发步骤

A) 创建原始对象(Service没有额外功能)


spring boot 两个服务互相注入 spring两个service事务_字符串_05


B) 创建额外功能Advice(接口)

Advice接口有四个子接口:

MethodBeforeAdvice(前置通知)

额外功能需要在原始方法执行之前执行。


spring boot 两个服务互相注入 spring两个service事务_代理类_06


AfterReturningAdvice(后置通知)

额外功能需要在原始方法执行之后执行。


spring boot 两个服务互相注入 spring两个service事务_字符串_07


MethodInterceptor(环绕通知)

注意:这个接口不是Spring提供的,是AopAliance提供的。

额外功能需要在原始方法执行之前和之后执行(最重要的功能就是控制事务)。


spring boot 两个服务互相注入 spring两个service事务_字符串_08


spring boot 两个服务互相注入 spring两个service事务_设计模式_09


ThrowsAdvice 额外功能需要在原始方法抛出异常时执行。(异常处理通知)

注意:ThrowsAdvice接口是一个没有定义方法的接口,我们称之为TagInterface标志性接口,这种标志性接口还有:Seriazable ThrowsAdvice Remote。

ThrowsAdvice接口的额外功能主要用于事务回滚。


spring boot 两个服务互相注入 spring两个service事务_代理类_10


C) 定义切入点(pointcut)

切入点决定了额外功能加入的位置。


spring boot 两个服务互相注入 spring两个service事务_字符串_11


1. 方法切入点

定义额外功能需要加入给哪些方法,上面execution(* *(..))就是一个典型的方法切入点。

注意:

切入点表达式最外层是一个切入点函数execution(),这是死的,真正活的是切入点函数里面的切入点表达式。

切入点表达式:* *(..)代表所有方法加入额外功能


spring boot 两个服务互相注入 spring两个service事务_代理类_12


按照要求写切入点表达式:

A) 为login方法加入额外功能:* login(..)

B) 为只有一个字符串参数的login方法加入额外功能:

* login(String)

注意:参数是String类型,而String类型是属于java.lang包中的,所以可以直接写String,如果参数不是java.lang包下面的类型,那么参数在书写的时候,必须写全限定名。比如:

* register(com.liw.User)

C) 为有两个字符串类型参数的login方法加入额外功能:

* login(String,String)

D) * login(String,..)表达的含义:login方法参数中第一个参数是String类型的,然后后面的参数没有要求,没有要求的意思是可以有其它参数,并且类型不限,也可以没有其它参数。

2. 类切入点

定义额外功能加入给哪个类,切入点表达式仍然写在execution()函数中。


spring boot 两个服务互相注入 spring两个service事务_设计模式_13