AspectJ:

什么是AOP:

AOP为Aspect Oriented Programming,意为:面向切面编程;它是一种思想一种设计典范(同Ioc);它是OOP(面向对象编程)的一种衍生。通过AOP对业务逻辑进行隔离,可以降低各个业务逻辑之间的耦合度。AOP主要解决的是”系统及服务“和”主业务逻辑“之间的耦合;

AOP和AspctJ:

AspecJ是一个基于java的AOP框架;spring自身也实现了AOP,在spring中一般使用AspectJ;

关系:AspectJ是AOP思想的实现,AOP实现方式有很多,著名的有spring AOP ,AspectJ;

AOP术语

  1. 目标类(target):需要被增强的类;

  2. 连接点(joinpoint):是指可以被增强到的方法;

  3. 切入点(Pointcut):已经被增强的方法(属于连接点中的方法)

  4. 通知(advice):指被增强的内容;

  5. 切面(Aspect):切面=切入点+通知;

  6. 织入(weaving):把“通知”应用到“目标类”中的过程;

    这个图描述的很好:

通知的类型

  • before:前置通知(应用:各种校验)

    • 在方法执行前执行,如果通知抛出异常,阻止方法运行
  • afterReturning:后置通知(应用:常规数据处理)
    • 方法正常返回后执行,如果方法中抛出异常,通知无法执行
    • 必须在方法执行后才执行,所以可以获得方法的返回值。
  • around:环绕通知(应用:十分强大,可以做任何事情)
    • 方法执行前后分别执行,可以阻止方法的执行
    • 必须手动执行目标方法
  • afterThrowing:抛出异常通知(应用:包装异常信息)
    • 方法抛出异常后执行,如果方法没有抛出异常,无法执行
  • after:最终通知(应用:清理现场)
    • 方法执行完毕后执行,无论方法中是否出现异常

切入点表达式

基本格式:

execution( 修饰符 返回值 包.类.方法名(参数) throws异常 )

括号中的内容其实就是声明一个方法。通常”修饰符“和”throw 异常“省略不写;

返回值:

基本类型,对象
*//(匹配任意返回值)

包:用限定名。可以使用通配符如:

com.abc.service//表示固定包
com.abc.crm.*.service//表示crm包下任意子包的service包
com.abc.crm..//表示crm包下面的所有子包(包括自己)
“..”可以表示自己本身和自己下面的多级包

类:可以使用固定名称,和统配符号

*Impl //以Impl结尾
User* //以User开头的
* //任意

方法名

addUser//固定方法
add*//以add开头
*Do//以Do结尾

参数

()//无参
(int)//一个整型
(int,int)//两个
(..)//参数任意

例子

execution(* *.someServiceImpl.*(..))
//所有的包下面(限定一级包)someServiceImpl类的所有任意参数的方法
execution(* *..someServiceImpl.*(..))
//所有的包下面(可以是多级包)someServiceImpl类的所有任意参数的方法
execution(* com.abc.crm.*.service..*.*(..))
//service下自己以及自己的子包的任意类的任意方法

基于xml的AspectJ编程

导入jar包

导入四个jar包

  • AspectJ的jar包
  • spring用于整合aspectJ的jar包
  • spring的AOP实现jar包
  • AOP联盟的AOP规范jar包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.0.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>

定义切面类

定义切面类用于写对应通知的方法

public class MyAspect {
public void before(){
System.out.println("执行前置通知before()!");
}
//可以输出当前的连接点
public void before2(JoinPoint jp){
System.out.println("执行前置通知before2() jp = "+ jp);
}
public void afterReturning(){
System.out.println("执行后置通知afterReturning()!");
}
//result接收目标方法的返回结果
//后置通知不能修改目标返回的返回结果本身
public void afterReturning2(Object res){
System.out.println("执行后置通知afterReturning2()目标方法的返回结果为result = "+ res +"aaa");
}
//环绕通知中来调用目标方法确定目标方法的执行时间
//环绕通知可以改变目标方法的返回结果本身
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行环绕通知-目标方法执行之前!");
//目标方法执行
Object proceed = pjp.proceed();
System.out.println("执行环绕通知-目标方法执行之后");
if (proceed != null){
proceed = proceed.toString().toUpperCase();
}
return proceed;
}
public void afterThrowing(){
System.out.println("执行异常通知afterThrowing()");
}
public void afterThrowing2(Exception ex){
System.out.println("执行异常通知afterThrowing2() ex = "+ex);
}
public void after(){
System.out.println("执行最终同时after()");
}
}

引入约束

引入spring对aop的约束即可

AOP配置

<!--注册切面:交叉业务逻辑对象-->
<bean id="myAspect" class="com.abc.service.MyAspect"/> <aop:config>
<!--定义切入点表达式-->
<aop:pointcut id=" " expression=""/>
<aop:pointcut id=" " expression=""/>
<!--配置切面-->
<!--切面为切入点+通知-->
<aop:aspect ref="myAspect">
<!--前置通知,引用切入点表达式-->
<aop:before method=" " pointcut-ref=""/>
<!--后置通知-->
<aop:after-returning method=" " pointcut-ref=" " returning="res"/>
<!--环绕通知-->
<aop:around method=" " pointcut-ref=" "/>
<!--异常通知-->
<aop:after-throwing method=" " pointcut-ref=" "/>
<!--最终通知-->
<aop:after method=" " pointcut-ref=" "/>
</aop:config>

基于注解的AspectJ编程

  1. 导入jar包

  2. 定义切面类

  3. 引入约束

  4. 注册AspectJ自动代理生成器

    <!--注册aspectj的自动代理-->
    <aop:aspectj-autoproxy/>
  5. 在切面类中添加注解

//切面:交叉业务逻辑
@Aspect //该类是切面类
public class MyAspect {
@Before("doFirstPC()")
public void before(){
System.out.println("执行前置通知before()!");
}
@Before("doAllPC()")
public void before2(JoinPoint jp){
System.out.println("执行前置通知before2() jp = "+ jp);
} @AfterReturning("doSecondPC()")
public void afterReturning(){
System.out.println("执行后置通知afterReturning()!");
}
//result接收目标方法的返回结果
//后置通知不能修改目标返回的返回结果本身
@AfterReturning(value = "doSecondPC()",returning = "res")
public void afterReturning2(Object res){
System.out.println("执行后置通知afterReturning2()目标方法的返回结果为result = "+ res +"aaa");
} //环绕通知中来调用目标方法确定目标方法的执行时间
//环绕通知可以改变目标方法的返回结果本身
@Around("doThirdPC()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行环绕通知-目标方法执行之前!");
//目标方法执行
Object proceed = pjp.proceed();
System.out.println("执行环绕通知-目标方法执行之后");
if (proceed != null){
proceed = proceed.toString().toUpperCase();
}
return proceed;
} @AfterThrowing("doSecondPC()")
public void afterThrowing(){
System.out.println("执行异常通知afterThrowing()");
}
@AfterThrowing(value = "doSecondPC()",throwing = "ex")
public void afterThrowing2(Exception ex){
System.out.println("执行异常通知afterThrowing2() ex = "+ex);
} @After("doSecondPC()")
public void after(){
System.out.println("执行最终同时after()");
} @Pointcut("execution(* *..SomeServiceImpl.doFirst())")
public void doFirstPC(){};
@Pointcut("execution(* *..SomeServiceImpl.doSecond())")
public void doSecondPC(){};
@Pointcut("execution(* *..SomeServiceImpl.doThird())")
public void doThirdPC(){};
@Pointcut("execution(* *..SomeServiceImpl.*())")
public void doAllPC(){};
}

spring中AspectJ的使用的更多相关文章

  1. SSM-Spring-18:Spring中aspectJ的XML版

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- aspectJ的xml版是开发中最常用的: 下面直接已案例入手,毕竟繁琐的日子不多了 案例:两个接口,俩个实现 ...

  2. SSM-Spring-17:Spring中aspectJ注解版

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- AspectJ AspectJ是一个面向切面的框架,它扩展了Java语言,定义了AOP 语法,能够在编译期提供 ...

  3. AspectJ在Spring中的使用

    在上一篇AspectJ的入门中,简单的介绍了下AspectJ的使用,主要是以AspectJ的example作为例子.介绍完后也留下了几个问题:1)我们在spring中并没有看到需要aspectj之类的 ...

  4. spring---aop(10)---Spring AOP中AspectJ

    写在前面 在之前的文章中有写到,Spring在配置中,会存在大量的切面配置.然而在很多情况下,SpringAOP 所提供的切面类真的不是很够用,比如想拦截制定的注解方法,我们就必须扩展DefalutP ...

  5. 在Spring中使用AspectJ实现AOP

    在Spring中,最常用的AOP框架是AspectJ,使用AspectJ实现AOP有2种方式: 基于XML的声明式AspectJ 基于注解的声明式AspectJ 基于XML的声明式AspectJ 1. ...

  6. Spring实战(十二) Spring中注入AspectJ切面

    1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...

  7. Spring 中基于 AOP 的 @AspectJ

    Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...

  8. Spring中文文档-第一部分

    一. Spring 框架概述 Spring是为了构建企业应用的轻量级框架.然而,Spring是模块化的,允许你只是使用其中的一部分,不需要引入其他的.你可以在任何web框架上使用IoC容器,也可以只使 ...

  9. Spring中文文档

    前一段时间翻译了Jetty的一部分文档,感觉对阅读英文没有大的提高(*^-^*),毕竟Jetty的受众面还是比较小的,而且翻译过程中发现Jetty的文档写的不是很好,所以呢翻译的兴趣慢慢就不大了,只能 ...

随机推荐

  1. [Gamma阶段]第七次Scrum Meeting

    Scrum Meeting博客目录 [Gamma阶段]第七次Scrum Meeting 基本信息 名称 时间 地点 时长 第七次Scrum Meeting 19/06/3 大运村寝室6楼 25min ...

  2. 利用python实现汉字转拼音

    安装:pip install pypinyin import pypinyin # 不带声调的(style=pypinyin.NORMAL) def pinyin(word): s = '' for ...

  3. Refused to execute script from '...' because its MIME type ('') is not executable, and strict MIME type checking is enabled.

    写在前面 部署项目到weblogic上启动首页访问空白, 浏览器控制台报如题错误. web.xml中把响应头添加防止攻击的报文过滤器禁用就行了(仅仅是为了启动), 以下为转载内容, 可以根据需要自行测 ...

  4. 【C++】C++的拷贝控制

    目录结构: contents structure [-] 拷贝.赋值与销毁 拷贝构造函数 拷贝初始化 参数和返回值 拷贝赋值运算符 析构函数 三五法则 拷贝控制和资源管理 交换操作 对象移动 右值引用 ...

  5. PHPUnit 单元测试教程

    一.官网下载对应 PHP 版本的代码库 https://phpunit.de/getting-started-with-phpunit.html 二.安装 PHPUnit 官网提供了两种方法安装 1. ...

  6. django使用mysql出现警告Warning: (3135, "'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release

    django使用mysql出现警告 Warning: (3135, "'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY ...

  7. linux命令(55):环境变量:LIBRARY_PATH 和 LD_LIBRARY_PATH的区别

    添加环境变量:https://www.cnblogs.com/lovychen/p/5583703.html PATH是可执行文件的环境变量. LIBRARY_PATH 和 LD_LIBRARY_PA ...

  8. python bottle + jieba分词服务

    2019-12-16 19:46:34 星期一 最近接触到结巴分词项目, 就试试 用python的bottle库来当服务器监听localhost:8080 把请求的数据转给jieba来分词, 并返回分 ...

  9. 浏览器查看和手动设置cookie的值

    1.查看:按F12进入浏览器的开发者模式——console——在命令行输入javascript:alert(document.cookie),再回车 2.按F12进入浏览器的开发者模式——consol ...

  10. shell基础知识6-在不按回车键的情况下读入N个字符

    Bash命令 read 能够从键盘或标准输入中读取文本.我们可以使用 read 以交互的形式读取用 户输入,不过 read 能做的可远不止这些.编程语言的大多数输入库都是从键盘读取输入,当回 车键按下 ...