Spring Aop基于注解的实现
一.AspectOriented Programing,面向切面编程。
AOP主要用于日志记录,性能统计,安全控制(权限控制),事务处理,异常处理等。将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
Spring AOP织入增强(Advice)的方式有两种 如果连接点实现了接口采用jdk自带的动态代理的形式实现织入,如果连接点没有实现接口则采用动态字节码生成技术(CGLIB)实现织入。
二.AOP常用术语:
连接点(Joinpoint)
增强程序执行的某个特定位置(要在哪个地方做增强操作)。Spring仅支持方法的连接点,既仅能在方法调用前,方法调用后,方法抛出异常时等这些程序执行点进行织入增强。
切点(Pointcut)
切点是一组连接点的集合。AOP通过“切点”定位特定的连接点。通过数据库查询的概念来理解切点和连接点的关系再适合不过了:连接点相当于数据库中的记录,而切点相当于查询条件。
增强(Advice)
增强是织入到目标类连接点上的一段程序代码。表示要在连接点上做的操作。
切面(Aspect)
切面由切点和增强(引介)组成(可以包含多个切点和多个增强),它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的链接点中。
注解切面类例子:

@Aspect
public class LogAspect {
@Pointcut("execution(* com.ctj.service.*.*(..))")
public void pointcutName(){} @Before("pointcutName()")
public void performance(){
System.out.println("Spring AOP");
}
}

三.常用注解:
- @aspect 定义切面
- @pointcut 定义切点
- @before 标注Before Advice定义所在的方法
- @afterreturning 标注After Returning Advice定义所在的方法
- @afterthrowing 标注After Throwing Advice定义所在的方法
- @after 标注 After(Finally) Advice定义所在的方法
- @around 标注Around Advice定义所在的方法
我们如何在定义切点(Pointcut)的时候指定一类Joinpoint呢?有两种方式 简单的方法名指定以及正则表达式两种方式。
四.常用的@AspectJ形式Pointcut表达式的标志符:
execution:
Spring AOP仅支持方法执行类型的Joinpoint 所以execution将会是我们用的最多的标志符,用它来帮我们匹配拥有指定方法前面的Joinpoint。匹配规则如下:
execution(modifiers-pattern? return-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern)
- modifiers-pattern 修饰符 比如public private这种(可以指定可以不指定)
- return-type-pattern 返回值类型(必须指定)
- declaring-type-pattern 类型(可以是含包名的全路径类型 可以指定可以不指定)
- name-pattern 方法名(必须指定)
- param-pattern 参数类型(必须指定)
方法的返回类型 方法名及参数部分的匹配模式是必须指定的 其他部分可以省略。
我们还可以在表达式中使用两种通配符:*和..
第一:*可以用于任何部分的匹配模式中,匹配相邻的多个字符,即一个Work 。如果放在了方法参数的位置标示参数是任何类型的。
例如:execution(* *(String))
第二:..通配符可以在两个位置使用 一个是declaring-type-pattern的位置,一个是在方法参数匹配模式的位置。
如果是放在了方法类型的位置,可以指定多个层次的类型声明。例如:
execution(void cn.spring.*.doSomething(*)) 指定到cn.spring下的所有类型。
如果是放在了方法参数的匹配位置,则表示该方法可以有0到多个参数。例如:
execution(void *.doSomething(..))
within:
within标志符只接受类型声明,它将匹配指定类型下所有的Joinpoint。
例如:within(cn.spring.aop.target.*) 将会匹配 cn.spring.aop.target包下所有类型的方法级别的Joinpoint。
@annotation
使用@annotation标志符会检查系统中所有对象的所有方法级别Joinpoint,如果被检测的方法标注有@annotation标志符所指定的注解类型,那么当前方法所在的Joinpoint将被Pointcut表达式匹配。例如:@pointcut("@annotation(com.test.aop.log.ALog)") 匹配所有使用了ALog注解的方法。
匹配表达式的维度有很多 上面只是一小部分常用的,并且这些维度是可以组合的 使用||或者$$等等
例如:@around("within(com.test.finance..*) && @annotation(com.test.finance.platform.intf.base.db.ReadOnly)")
在定义Advice的时候 我们匹配的维度可以直接写定义有@pointcut的方法名称 也可以直接使用定义@joinpoint的那一套东西来直接定义要在哪些地方织入(可以直接在Advice上指定匹配哪些方法)
定义完切面之后我们要在spring中注册这个切面类,为了让spring能自动帮我们实现织入 我们还需要开启自动注入 在spring配置文件中:<aop:aspectj-autoproxy proxy-target-class="true"/> 这样spring就能在IOC容器找到所有要织入的方法 动态帮我们织入。
五.一个完整的Spring AOP的小例子:
业务类代码:

package com.ctj.service;
import org.springframework.stereotype.Service; @Service
public class BusinessService { public void say(){
System.out.println("Business Code");
}
}

切面类定义:

package com.ctj.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; @Aspect
public class LogAspect {
@Pointcut("execution(* com.ctj.service.*.*(..))")
public void pointcutName(){}
@Before("pointcutName()")
public void performance(){
System.out.println("Spring AOP");
}
}

spring-aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="logAspect" class="com.ctj.aspect.LogAspect">
</bean>
</beans>

基于注解的Spring AOP需要JDK1.5版本以后才能使用,之前的版本需要使用基于Schema也就是配置文件的形式来实现,如果jdk版本高的话 建议还是使用注解的形式。
Spring Aop基于注解的实现的更多相关文章
- spring-第十七篇之spring AOP基于注解的零配置方式
1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...
- Spring AOP基于注解的“零配置”方式实现
为了在Spring中启动@AspectJ支持,需要在类加载路径下新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar.除此之外,Spring AOP还需要依赖一个a ...
- Spring AOP基于配置文件的面向方法的切面
Spring AOP基于配置文件的面向方法的切面 Spring AOP根据执行的时间点可以分为around.before和after几种方式. around为方法前后均执行 before为方法前执行 ...
- Spring:基于注解的Spring MVC
什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- spring aop 使用注解方式总结
spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- (转)利用Spring AOP自定义注解解决日志和签名校验
一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...
随机推荐
- java实现多线程(车站卖票)
import java.util.ArrayList; import java.util.List; public class 多线程 { // public static int j=0; publ ...
- java实现Playfair 密码
一种 Playfair 密码变种加密方法如下:首先选择一个密钥单词(称为 pair)(字母不重复,且都为小写字母), 然后与字母表中其他字母一起填入至一个 5x5 的方阵中,填入方法如下: 1.首先按 ...
- org.openqa.selenium.WebDriverException: It is impossible to create a new session because 'createSession' which takes HttpClient, InputStream and long was not found or it is not accessible 异常
检查项目配置的jdk版本是否过低,修改一下配置就解决了.如果是jdk版本过低的就升级一下jdk.
- BitMap算法及其实现(Python)
BitMap概述 本文介绍 BitMap 算法的应用背景,算法思想和相关实现细节. 概括而言,BitMap 主要用来解决海量数据中元素查询,去重.以及排序等问题.这里对海量数据场景的强调,似乎暗示了这 ...
- 小师妹学JavaIO之:目录还是文件
目录 简介 linux中的文件和目录 目录的基本操作 目录的进阶操作 目录的腰疼操作 总结 简介 目录和文件傻傻分不清楚,目录和文件的本质到底是什么?在java中怎么操纵目录,怎么遍历目录.本文F师兄 ...
- 解读三组容易混淆的Dockerfile指令
长话短说,今天分享三组容易混淆的Dockerfile指令, 帮助大家编写更优雅的Dockfile文件.构建更纯净的Docker镜像. COPY vs ADD COPY.ADD主体功能类似:从指定位置拷 ...
- ReentrantLock原理分析
一 UML类图 通过类图ReentrantLock是同步锁,同一时间只能有一个线程获取到锁,其他获取该锁的线程会被阻塞而被放入AQS阻塞队列中.ReentrantLock类继承Lock接口:内部抽象类 ...
- 环境篇:CM+CDH6.3.2环境搭建(全网最全)
环境篇:CM+CDH6.3.2环境搭建(全网最全) 一 环境准备 1.1 三台虚拟机准备 Master( 32g内存 + 100g硬盘 + 4cpu + 每个cpu2核) 2台Slave( 12g内存 ...
- mysql 大表mysqldump迁移方案
场景 一张历史表product_history 500万数据,凌晨的才会将正式表的数据迁移到历史表,此次需求将历史表迁移到一个更便宜的数据库实例进行存储. 条件 1.此表不是实时写,凌晨才会更新 2. ...
- 君荣 TS--8200 消费机显示说明
Err 001——不在消费时段内Err 002——非本系统卡Err 003——余额不足Err 004——级别未开放Err 005——卡已挂失Err 006——有效期未生效Err 007——已过有效期 ...