您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页SpringAop基于注解的实现

SpringAop基于注解的实现

来源:化拓教育网
SpringAop基于注解的实现

⼀.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\"); }}

三.常⽤注解:

定义切⾯ 定义切点

标注Before Advice定义所在的⽅法

@afterreturning 标注After Returning Advice定义所在的⽅法@afterthrowing 标注After Throwing Advice定义所在的⽅法 标注 After(Finally) Advice定义所在的⽅法 标注Around Advice定义所在的⽅法

我们如何在定义切点(Pointcut)的时候指定⼀类Joinpoint呢?有两种⽅式 简单的⽅法名指定以及正则表达式两种⽅式。

四.常⽤的形式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。

  使⽤标志符会检查系统中所有对象的所有⽅法级别Joinpoint,如果被检测的⽅法标注有标志符所指定的注解类型,那么当前⽅法所在的Joinpoint将被Pointcut表达式匹配。例如:(\"(com.test.aop.log.ALog)\") 匹配所有使⽤了ALog注解的⽅法。匹配表达式的维度有很多 上⾯只是⼀⼩部分常⽤的,并且这些维度是可以组合的 使⽤||或者$$等等例如:(\"within(com.test.finance..*) && (com.test.finance.platform.intf.base.db.ReadOnly)\")

在定义Advice的时候 我们匹配的维度可以直接写定义有的⽅法名称 也可以直接使⽤定义@joinpoint的那⼀套东西来直接定义要在哪些地⽅织⼊(可以直接在Advice上指定匹配哪些⽅法)

定义完切⾯之后我们要在spring中注册这个切⾯类,为了让spring能⾃动帮我们实现织⼊ 我们还需要开启⾃动注⼊ 在spring配置⽂件中: 这样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

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\">

基于注解的Spring AOP需要JDK1.5版本以后才能使⽤,之前的版本需要使⽤基于Schema也就是配置⽂件的形式来实现,如果jdk版本⾼的话 建议还是使⽤注解的形式。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务