博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【JAVA笔记——器】Spring面向切面编程 Aspect Oriented Programming with Spring
阅读量:7095 次
发布时间:2019-06-28

本文共 6334 字,大约阅读时间需要 21 分钟。

并非完全按照Reference翻译,有删改

原文

AOP术语

通知Advice

切面的工作为通知
SPRING 五种通知
before after after-returning after-throwing around

连接点 Joinpoint

连接点是执行过程中能够插入切面的一个点

切点 Pointcut

并非所有连接点都需要被通知,切点定义匹配通知所要织入的一个多或多个连接点

切面 Aspect

切面是通知和切点的结合。定义切面的如何实现

引入 Inteoduction

引入允许我们向现有的类添加新方法或属性

织入 Weaving

织入是将切面应用到目标对象创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。目标对象的生命周期有多个点可以织入

  • 编译期
  • 类加载期
  • 运行期

配置

@Aspect

Aspect注解切面对象

package org.xyz;import org.aspectj.lang.annotation.Aspect;@Aspectpublic class NotVeryUsefulAspect {}

切点

AspectJ包含的不支持

call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, and @withincode
使用报出IllegalArgumentException

execution - 连接点匹配方法,这是在Sring AOP主要的使用的切点设计器within - 限制匹配连接点在特定类型,相当于简化的execution方法this - 限制匹配连接点所对应Bean引用是特定类型args - 限制匹配连接点的参数列表是特定类型@target - 限制匹配连接点对应的类的对象拥有所标记的的类型@args - 限制匹配连接点对应的类运行时参数是所标记的类型@within - 限制匹配连接点在标注的类中@annotation - 限制匹配连接点,连接点的主体被注解

execution - for matching method execution join points, this is the primary pointcut designator you will use when working with Spring AOP

within - limits matching to join points within certain types (simply the execution of a method declared within a matching type when using Spring AOP)

this - limits matching to join points (the execution of methods when using Spring AOP) where the bean reference (Spring AOP proxy) is an instance of the given type

target - limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type

args - limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types

@target - limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type

@args - limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given type(s)

@within - limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP)

@annotation - limits matching to join points where the subject of the join point (method being executed in Spring AOP) has the given annotation

原生Spring AOP基于代理(无论是JDK Proxy/CGLIB),均无法对可访问性小于protected的类进行代理。

如果需要,可以使用Spring-driven native AspectJ weaving

Spring AOP支持PCD命名Bean,idOrNameOfBean支持* , &&, ||

bean(idOrNameOfBean)

Demo

@Pointcut("execution(public * *(..))")private void anyPublicOperation() {}@Pointcut("within(com.xyz.someapp.trading..*)")private void inTrading() {}@Pointcut("anyPublicOperation() && inTrading()")private void tradingOperation() {}

官方提供公共配置

package com.xyz.someapp;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;@Aspectpublic class SystemArchitecture {    /**     * A join point is in the web layer if the method is defined     * in a type in the com.xyz.someapp.web package or any sub-package     * under that.     */    @Pointcut("within(com.xyz.someapp.web..*)")    public void inWebLayer() {}    /**     * A join point is in the service layer if the method is defined     * in a type in the com.xyz.someapp.service package or any sub-package     * under that.     */    @Pointcut("within(com.xyz.someapp.service..*)")    public void inServiceLayer() {}    /**     * A join point is in the data access layer if the method is defined     * in a type in the com.xyz.someapp.dao package or any sub-package     * under that.     */    @Pointcut("within(com.xyz.someapp.dao..*)")    public void inDataAccessLayer() {}    /**     * A business service is the execution of any method defined on a service     * interface. This definition assumes that interfaces are placed in the     * "service" package, and that implementation types are in sub-packages.     *     * If you group service interfaces by functional area (for example,     * in packages com.xyz.someapp.abc.service and com.xyz.someapp.def.service) then     * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"     * could be used instead.     *     * Alternatively, you can write the expression using the 'bean'     * PCD, like so "bean(*Service)". (This assumes that you have     * named your Spring service beans in a consistent fashion.)     */    @Pointcut("execution(* com.xyz.someapp..service.*.*(..))")    public void businessService() {}    /**     * A data access operation is the execution of any method defined on a     * dao interface. This definition assumes that interfaces are placed in the     * "dao" package, and that implementation types are in sub-packages.     */    @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")    public void dataAccessOperation() {}}

匹配规则

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

ret-type-pattern | name-pattern | param-pattern必选,其他可选

modifiers-pattern 修饰语匹配 : public *匹配任意类型

ret-type-pattern 返回类型匹配 : Object *匹配任意类型
declaring-type-pattern 定义类型匹配 : com.cunchen.entity.Test *匹配任意类型
name-pattern 方法名匹配 : testMethod *匹配任意方法
param-pattern 参数匹配 : Object | ()无参数 | (..)任意参数 | ()任意一个参数 | ( , String) 任意一个参数 + 一个String参数

//匹配public方法execution(public * *(..))//匹配开始名称setexecution(* set*(..))//匹配AccountService的子类实现方法execution(* com.xyz.service.AccountService.*(..))//匹配com.xyz.servic包下接口的子类实现方法execution(* com.xyz.service.*.*(..))//在com.xyz.service包中的任意连接点within(com.xyz.service.*)//在com.xyz.service包以及子包中的任意连接点within(com.xyz.service..*)//代理接口AccountService的任意连接点this(com.xyz.service.AccountService)//任意实现AccountService接口实现对象的连接点target(com.xyz.service.AccountService)//任意只有一个参数,且参数在运行时是Serializable的任意连接点args(java.io.Serializable)//任意目标对象被注解为@Transactional的连接点@target(org.springframework.transaction.annotation.Transactional)//任意目标对象的声明中拥有@Transactional@within(org.springframework.transaction.annotation.Transactional)//任意连接点被注释@Transactional@annotation(org.springframework.transaction.annotation.Transactional)//任意连接点,它接受一个参数,并且传入的参数的运行时类型有@Classified注解@args(com.xyz.security.Classified)//任意 Spring bean 命名为 tradeService 的连接点bean(tradeService)//任意 Spring bean 符合通配符统配为 *Service 的连接点bean(*Service)

转载于:https://www.cnblogs.com/cunchen/p/9464135.html

你可能感兴趣的文章
Android编程之常识 - 混淆
查看>>
源码分析六(org.springframework.util包之Assert类)
查看>>
源码分析八(org.springframework.util包之StringUtils类))
查看>>
#include<> 和 #include""的区别
查看>>
【转】最近很火的 Safe Area 到底是什么
查看>>
java EE 环境配置(JDK + Tomcat + Eclipse for java EE)
查看>>
【转】【Python】Python正则表达式使用指导
查看>>
c#去掉guid中间的横杆
查看>>
Java架构-(十二) 整合spring cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
查看>>
ReactNative干货分享——视频播放器App
查看>>
详解 PHP 数组的底层实现:HashTable
查看>>
函数式点滴--partial&curry
查看>>
wokerman启动分析
查看>>
PHP数组排序算法实现(14种)
查看>>
CSS3总结系列0
查看>>
centos6.5和centos7如何搭建php环境
查看>>
Android ImageLoader 实现
查看>>
Swift Notes 0x00 前言
查看>>
[Violent Python for Hackers]常用工具收集整理
查看>>
一个后端的前端学习之旅——2.先搞定gulp
查看>>