Aop
Aop 为 Aspect Oriented Programming 的缩写,即面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。他通过对已有程序定一个切入点,然后在其前后切入不同的执行内容。比如常见的有:打开数据库连接/关闭数据库连接、打开事务/关闭事务、记录日志等。基于AOP不会破坏原来程序逻辑,因此它可以很好的对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
注解
-
@Aspect(切面):
把当前类标识为一个切面类供容器读取 -
@Before:
标识一个前置增强方法,,相当于BeforeAdvice
-
@After:
不管是抛出异常或者正常退出都会执行 -
@AfterThrowing:
异常抛出增强,相当于ThrowsAdvice
-
@AfterReturning:
后置增强,相当于AfterReturningAdvice
,方法正常退出时执行 -
@Around:
环绕增强,相当于MethodInterceptor
-
@DeclareParents:
引介增强,相当于IntroductionInterceptor
-
@Pointcut(切点):
切面类中负责增强的方法,在实际操作中,实际负责增强的方法叫切入点。常与execution
表达式一起用 -
JoinPoint(连接点):
类里面的被增强的方法 -
@Order:
一个 web 应用会配置多个切面,所以这时就有了先后顺序。@Order(value = )
注解中的值越小优先级越高。执行顺序是这样的:- 在
@Before
中优先执行@Order(5)
的内容,再执行@Order(10)
的内容 - 在
@After
和@AfterReturning
中优先执行@Order(10)
的内容,再执行@Order(5)
的内容
- 在
execution 切点函数
语法为:
execution( 方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选) )
execution(public * nuc.jyg.chapter9.controller.UserController.*(..))
- 参数部分允许使用通配符:
-
*
匹配任意字符,但只能匹配一个元素`(*)`` - ``..
匹配任意字符,可以匹配任意多个元素,表示类时,必须和
*联合使用。
+必须跟在类名后面,如
User+`,表示类本身和继承或扩展指定类的所有类
-
所以以上表达式可以解析为:
名称 | 意义 |
---|---|
方法修饰符 | public |
返回类型 |
* 匹配任意数量字符,表示返回类型不限 |
方法名 |
nuc.jyg.chapter9.controller.UserController.* 表示匹配UserController 类下的所有方法 |
参数 |
(..) 表示匹配任意数量和类型的输入参数 |
异常模式 | 不限 |
更多示例:
void aop(String,int)
匹配目标类任意修饰符方法、返回
void
、方法名aop
、带有一个String
和一个int
型参数的方法
public void aop(*)
匹配目标类
public
修饰、返回void
、方法名aop
、带有一个任意类型参数的方法
public String *o*(..)
匹配目标类
public
修饰、返回String
类型、方法名中带有一个o字符、带有任意数量任意类型参数的方法
public void *o*(String,..)
匹配目标类
public
修饰、返回void
、方法名中带有一个o字符、带有任意数量任意类型参数,但第一个参数必须有且为String
型的方法
也可以指定类:
public void nuc.jyg.chapter9.controller.UserController.*(..)
匹配
UserController
的public
修饰、返回void
、不限方法名、带有任意数量任意类型参数的方法
public void void nuc.jyg.chapter9.controller.*Controller.*(..)
匹配以
Controller
结尾的类中public
修饰、返回void
、不限方法名、带有任意数量任意类型参数的方法
指定包:
public void nuc.jyg.chapter9.controller.*.aop(..)
匹配
nuc.jyg.chapter9.controller
包下所有类中public
修饰、返回void
、方法名aop
、带有任意数量任意类型参数的方法
public void nuc.jyg..*.aop(..)
匹配
nuc.jyg.
包下和所有子包中的类中public
修饰、返回void
、方法名aop
、带有任意数量任意类型参数的方法
更多切点函数
除了execution()
,Spring 中还支持其他多个函数,这里列出名称和简单介绍,以方便根据需要进行更详细的查询
- annotation()
表示标注了指定注解的目标类方法
例如@annotation(org.springframework.transaction.annotation.Transactional)
表示标注了@Transactional
的方法
- args()
通过目标类方法的参数类型指定切点
例如args(String)
表示有且仅有一个String
型参数的方法
- @args()
通过目标类参数的对象类型是否标注了指定注解指定切点
如@args(org.springframework.stereotype.Service)
表示有且仅有一个标注了@Service
的类参数的方法
- within()
通过类名指定切点
如with(nuc.jyg.chapter9.controller.UserController)
表示UserController
的所有方法
- target()
通过类名指定,同时包含所有子类
如target(nuc.jyg.chapter9.controller.UserController)
且ManController extends UserController
,则两个类的所有方法都匹配
- @within()
匹配标注了指定注解的类及其所有子类
如@within(org.springframework.web.bind.annotation)
给UserController
加上@RestController
标注,则UserController
和ManController
的所有方法都匹配
- @target()
所有标注了指定注解的类
如@target(org.springframework.stereotype.Service)
表示所有标注了@Service
的类的所有方法
- this()
大部分时候和target()
相同,区别是this
是在运行时生成代理类后,才判断代理类与指定的对象类型是否匹配
逻辑运算符
表达式可由多个切点函数通过逻辑运算组成
&&
与操作,求交集,也可以写成and
例如execution(* aop(..)) && target(User)
表示User
及其子类的aop
方法
||
或操作,求并集,也可以写成or
例如execution(* aop(..)) || args(String)
表示名称为aop
的方法或者有一个String
型参数的方法
!
非操作,求反集,也可以写成not
例如execution(* aop(..)) and !args(String)
表示名称为aop
的方法但是不能是只有一个String
型参数的方法
网友评论