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. 主题模型(LDA)(一)--通俗理解与简单应用

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_39422642/article/de ...

  2. 【深入学习linux】在linux系统下怎么编写c语言程序并运行

    1. 首先安装下 gcc : centos yum -y gcc 2. 编写c程序保存hello.c: #include <stdio.h> #include <stdlib.h&g ...

  3. 工具系列 | PHPSTROM 连接Docker容器 && 配置XDEBUG调试

    Docker 客户端配置 PHPSTROM 配置 选择连接 容器日志 配置Xdebug 开启Debug模式 打断点 浏览器访问该项目地址:http://wiot.frp.tinywan.top/

  4. JPA的一对多,多对多用法

    一.@OneToOne关系映射 JPA使用@OneToOne来标注一对一的关系. 实体 People :用户. 实体 Address:家庭住址. People 和 Address 是一对一的关系. 这 ...

  5. xshell如何导入.xsh 文件

    xshell 不能导入 xsh 文件 导入功能 只能导入 *.xts, *.csv, *.tsv 文件,不能直接导入 .xsh 其实 xsh文件不需要导入,直接拷贝进去就可以了(.xsh 本来就是 x ...

  6. ip rule实现源IP路由,实现一个主机多IP(或多网段)同时通(外部看是完全两个独立IP)

    利用ip rule实现基于源地址区分路由表,实现一个主机多IP网段同时通.(外部的一个主机无论访问哪个网段都可以访问通)实际应用:创建路由表table200ip route add 192.168.1 ...

  7. EmuELEC系统的结构

    分区结构 在img写入后, 会产生两个分区EMUELEC: 用于启动的文件, 例如dtb文件等, 以及system.img & system.img.md5, EmuELEC的系统文件都在这个 ...

  8. 两行命令查看自己笔记本连接的wifi密码

    打开cmd.exe窗口 第一行命令 netsh wlan show profiles 可以查看所有曾经连接过的wifi 第二命令 netsh wlan show profiles "vivo ...

  9. Google软件测试之道笔记与总结

    [本文出自天外归云的博客园] 以下内容除了笔记还有总结,有个人理解的成分在内. 第一章笔记与总结 1. 开发人员也承担了质量的重任,质量从来就不仅仅是一些测试人员的问题.头衔有测试字样的人的任务是让那 ...

  10. ROS2 在WIN10下测试和安装

    博客参考:https://blog.csdn.net/cocoiehl/article/details/83351307 和 https://blog.csdn.net/weixin_38294178 ...