1、概念

(1)AspectJ是一个基于Java语言的AOP框架

(2)Spring2.0以后新增了对AspectJ切入点表达式的支持

(3)AspectJ是AspectJ1.5的新增功能,通过JDK5注解技术,允许在Bean类中定义切面。新版本的Spring框架建议使用AspectJ方式来开发AOP

2、切入点表达式

(1)execution():用语描述方法

语法:execution(修饰符、返回值、包、类、方法(参数)、异常)

修饰符:一般省略

public:公共方法

*:任意

返回值

void:没有返回值

String:返回值为字符串

*:返回值任意

方法:不能省略

参数

(..)参数任意

(2)案例:

 <aop:pointcut id="myPointCut" expression="execution(* pers.zhb.proxy.*.*(..))"></aop:pointcut>

(3)其他表达式

within:匹配包或者子包中的方法

this:匹配接口中代理对象中的方法

target:匹配实现接口的目标对象的方法

args:匹配参数格式符合标准的方法

bean:对指定bean所有的方法

2、AspectJ通知类型

(1)aop联盟定义通知类型:具有特性接口,必须实现,从而确定方法名称。
(2)aspectj通知类型:只定义类型名称。已经方法格式。
before:前置通知(应用:各种校验)

在方法执行前执行,如果通知抛出异常,阻止方法运行

afterRetuming:后置通知(应用:常规数据处理)

方法正常返回后执行,如果方法中抛出异常,通知无法执行

必须在方法执行后才执行,所以可以获得方法的返回值

around:环统通知(应用:十分强大,可以做任何事情)

方法执行前后分别执行,可以阻止方法的执行。
必须手动执行目标方法

afterThrowing:抛出异常通知(应用:包装异常信息)

方法抛出异常后执行,如果方法没有抛出异常,无法执行

after最终通知(应用:清理现场)

方法执行完毕后执行,无论方法中是否出现异常

3、导入jar包(四个)

aop联盟规范

spring aop实现

aspect规范

spring aspect实现

4、源码

(1)AspectJAfterThrowingAdvice

(2)AspectJAfterAdvice

5、基于XML文件的配置(前置通知)

(1)目标类的接口和实现类:

public interface StudentService {
void addStudent();
void updateStudent();
void deleteStudent();
}
public class StudentServiceImpl implements StudentService {
@Override
public void addStudent() {
System.out.println("addStudent");
} @Override
public void updateStudent() {
System.out.println("updateStudent");
} @Override
public void deleteStudent() {
System.out.println("deleteStudent");
}
}

(2)切面类(含有通知):

public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
}
}

(3)配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--目标类-->
<bean id="studentService" class="pers.zhb.aspectxml.StudentServiceImpl"></bean>
<!--切面类-->
<bean id="myAspect" class="pers.zhb.aspectxml.MyAspect"></bean>
<!--aop编程
将切面类声明为切面,从而获得通知(方法)
ref:切面类引用
-->
<aop:config>
<aop:aspect ref="myAspect">
<!--引入切面类,从中获得通知(方法)
expression:切入点表达式
id:名称,用于其他通知引用
-->
<aop:pointcut id="myPointCut" expression="execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))"></aop:pointcut>
<!--
method:通知,即方法名
pointcut:切入点表达式,此表达式只能当前通知使用
pointcut-ref:切入点的引用,可以和其它通知共享切入点
-->
<aop:before method="before" pointcut-ref="myPointCut"></aop:before>
</aop:aspect>
</aop:config>
</beans>

(4)测试类:

public class TestAspectXml {
public static void main(String[] args) {
ApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
//获得目标类
pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
studentService.addStudent();
studentService.deleteStudent();
studentService.updateStudent();
}
}
前置通知:addStudent
addStudent
前置通知:deleteStudent
deleteStudent
前置通知:updateStudent
updateStudent

6、基于XML文件的配置(后置通知)

(1)定义接口和接口的实现类:

public interface StudentService {
void addStudent();
void updateStudent();
String deleteStudent();
}
public class StudentServiceImpl implements StudentService {
@Override
public void addStudent() {
System.out.println("addStudent");
} @Override
public void updateStudent() {
System.out.println("updateStudent");
} @Override
public String deleteStudent() {
System.out.println("deleteStudent");
return "nihao";
}
}

(2)切面类:

public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
} public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
//参数二:类型Object,参数名returning配置的
System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
}
}

(3)配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--目标类-->
<bean id="studentService" class="pers.zhb.aspectxml.StudentServiceImpl"></bean>
<!--切面类-->
<bean id="myAspect" class="pers.zhb.aspectxml.MyAspect"></bean>
<!--aop编程
将切面类声明为切面,从而获得通知(方法)
ref:切面类引用
-->
<aop:config>
<aop:aspect ref="myAspect">
<!--引入切面类,从中获得通知(方法)
expression:切入点表达式
id:名称,用于其他通知引用
-->
<aop:pointcut id="myPointCut" expression="execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))"></aop:pointcut>
<!--
method:通知,即方法名
pointcut:切入点表达式,此表达式只能当前通知使用
pointcut-ref:切入点的引用,可以和其它通知共享切入点
returning:通知方法第二个参数的名称
-->
<aop:before method="before" pointcut-ref="myPointCut"></aop:before>
<aop:after-returning method="after" pointcut-ref="myPointCut" returning="ret"></aop:after-returning> </aop:aspect>
</aop:config>
</beans>

(4)测试类:

public class TestAspectXml {
public static void main(String[] args) {
ApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
//获得目标类
pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
studentService.addStudent();
studentService.deleteStudent();
studentService.updateStudent();
}
}
前置通知:addStudent
addStudent
后置通知:addStudent null
前置通知:deleteStudent
deleteStudent
后置通知:deleteStudent nihao
前置通知:updateStudent
updateStudent
后置通知:updateStudent null

7、基于XML文件的配置(环绕通知)

(1)切面类:

public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
} public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
//参数二:类型Object,参数名returning配置的
System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
}
public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
//手动执行目标方法
System.out.println("前");
Object object=proceedingJoinPoint.proceed();
System.out.println("后");
return null;
}
}

(2)配置文件:

 <aop:around method="around" pointcut-ref="myPointCut"></aop:around>

(3)测试结果:

前置通知:addStudent
前
addStudent
后
后置通知:addStudent null
前置通知:deleteStudent
前
deleteStudent
后
后置通知:deleteStudent null
前置通知:updateStudent
前
updateStudent
后
后置通知:updateStudent null

8、基于XML文件的配置(抛出异常)

(1)定义目标类的接口和接口的实现类:

public interface StudentService {
void addStudent();
void updateStudent();
String deleteStudent();
}

在方法中制造异常:

public class StudentServiceImpl implements StudentService {
@Override
public void addStudent() {
System.out.println("addStudent");
} @Override
public void updateStudent() {
int num=9/0;
System.out.println("updateStudent");
} @Override
public String deleteStudent() {
System.out.println("deleteStudent");
return "nihao";
}
}

(2)切面类:

public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
} public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
//参数二:类型Object,参数名returning配置的
System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
}
public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
//手动执行目标方法
System.out.println("前");
Object object=proceedingJoinPoint.proceed();
System.out.println("后");
return null;
}
public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常的通知:"+throwable.getMessage());
}
}

(3)配置文件:

 <aop:after-throwing method="AfterThrowing" pointcut-ref="myPointCut" throwing="throwable"></aop:after-throwing>

(4)测试:

前置通知:addStudent
前
addStudent
后
后置通知:addStudent null
前置通知:deleteStudent
前
deleteStudent
后
后置通知:deleteStudent null
前置通知:updateStudent
前
抛出异常的通知:/ by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero

9、基于XML文件的配置(最终通知)

(1)目标类的接口和接口的实现类:

public interface StudentService {
void addStudent();
void updateStudent();
String deleteStudent();
}
public class StudentServiceImpl implements StudentService {
@Override
public void addStudent() {
System.out.println("addStudent");
} @Override
public void updateStudent() {
int num=9/0;
System.out.println("updateStudent");
} @Override
public String deleteStudent() {
System.out.println("deleteStudent");
return "nihao";
}
}

(2)切面类:

public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
} public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
//参数二:类型Object,参数名returning配置的
System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
}
public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
//手动执行目标方法
System.out.println("前");
Object object=proceedingJoinPoint.proceed();
System.out.println("后");
return null;
}
public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常的通知:"+throwable.getMessage());
} public void myafter(JoinPoint joinPoint){
System.out.println("最终通知");
}
}

(3)配置文件:

 <aop:after method="myafter" pointcut-ref="myPointCut"></aop:after>

(4)测试结果:

前置通知:addStudent
前
addStudent
最终通知
后

后置通知:addStudent null
前置通知:deleteStudent
前
deleteStudent
最终通知
后

后置通知:deleteStudent null
前置通知:updateStudent
前
最终通知
抛出异常的通知:/ by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero

不管有没有异常都会执行最终通知。

10、基于注解的配置

(1)目标类的接口和接口的实现类:

public interface StudentService {
void addStudent();
void updateStudent();
String deleteStudent();
}
import org.springframework.stereotype.Service;
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Override
public void addStudent() {
System.out.println("addStudent");
} @Override
public void updateStudent() {
int num=9/0;
System.out.println("updateStudent");
} @Override
public String deleteStudent() {
System.out.println("deleteStudent");
return "nihao";
}
}

(2)配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描注解-->
<context:component-scan base-package="pers.zhb.aspectxml"></context:component-scan>
<!--确定aop注解生效-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

(3)切面:

@Component
@Aspect//声明切面
public class MyAspect {
@Before("execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+ joinPoint.getSignature().getName());
} //声明公共切入点
@Pointcut("execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))")
private void myPointCut(){ }
@AfterReturning(value = "myPointCut()",returning = "ret")
public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
//参数二:类型Object,参数名returning配置的
System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
} @Around(value = "myPointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
//手动执行目标方法
System.out.println("前");
Object object=proceedingJoinPoint.proceed();
System.out.println("后");
return null;
} @AfterThrowing(value = "execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))",throwing = "throwable")
public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
System.out.println("抛出异常的通知:"+throwable.getMessage());
} @After(value = "myPointCut()")
public void myafter(JoinPoint joinPoint){
System.out.println("最终通知");
}
}

(4)测试:

public class TestAspectXml {
public static void main(String[] args) {
ApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
//获得目标类
pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
studentService.addStudent();
studentService.deleteStudent();
studentService.updateStudent();
}
}
前
前置通知:addStudent
addStudent
后
最终通知
后置通知:addStudent null
前
前置通知:deleteStudent
deleteStudent
后
最终通知
后置通知:deleteStudent null
前
前置通知:updateStudent
最终通知
抛出异常的通知:/ by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero

spring的AspectJ基于XML和注解(前置、后置、环绕、抛出异常、最终通知)的更多相关文章

  1. Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理

    1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...

  2. spring之AspectJ基于xml AOP编程

    一.引言: AspectJ框架不仅实现了面向切面编程,而且还支持注解,spring将它引入自己的规范之中. 二.需要了解: AspectJ是基于java语言的AOP框架 spring2.0之后支持As ...

  3. MyBatis 项目开发中是基于 XML 还是注解?

    只要你对 MyBatis 有所认识和了解,想必知道 MyBatis 有两种 SQL 语句映射模式,一种是基于注解,一种是基于XML. 基于 XML <mapper namespace=" ...

  4. spring 切面 前置后置通知 环绕通知demo

    环绕通知: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...

  5. Spring Bean前置后置处理器的使用

    Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...

  6. AOP 环绕通知 集成了前置 后置 返回通知等功能

    AOP 环绕通知 集成了前置 后置 返回通知等功能

  7. pytest_前置后置

    今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...

  8. unittest的前置后置,pytest的fixture和共享机制conftest.py

    Unittest setUp/tearDown setUp当中得到的变量,用self.xxx = value传递给测试用例 setUpClass/tearDownClass setupClass当中得 ...

  9. spring之AspectJ基于注解 AOP编程

    一.前言 使用注解代替之前在spring配置文件中配置目标类.切面类和aop配置. 二.注意 需要注意的是,需要在spring配置文件中引入如下,如果不添加,切面类中的@Aspect注解将不起作用 & ...

随机推荐

  1. Java 接口 抽象类 抽象方法

    abstract class elehousekeeping { //抽象家用电器类 abstract void opermode(); //抽象方法} class TV extends elehou ...

  2. 树链剖分详解&题解 P6098 【[USACO19FEB]Cow Land G】

    看到各位大佬们已经把其他的东西讲的很明白了,我这个 juruo 就讲一讲最基本的树链剖分吧. 0.树剖是什么?能吃吗? 不能吃 树剖是树链剖分的简称,我们一般说的树剖其实指重链剖分.当然,还有一种长链 ...

  3. 23种设计模式 - 数据结构(Composite - iterator - Chain of Responsibility)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 数据结构 Composite 动机(Motivation) 软件在某些情况下,客户代码过多依赖于对象容器复 ...

  4. 用 Java 拿下 HTML 分分钟写个小爬虫

    本文适合有 Java 基础知识的人群 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一款开源 Java 版一款网页元素解析框架- ...

  5. 屏幕适配 部分知识点总结,CSDN小冰原创

    /** * 作者:David Zheng on 2015/11/7 15:38 * *  网站:http://www.93sec.cc * *  微博:http://weibo.com/mcxiaob ...

  6. django学习(二)

    1.反向解析 什么是方向解析呢? 通过一些方法得到一个结果,该结果可以直接访问对应url出发视图函数. 先给一个路由和视图函数起一个别名.但是我们要注意的是反向解析的别名是不可以冲突的!!!不然会出现 ...

  7. 理解WEB系统

    网络应用及分类 BS架构:Browser/Server web应用的客户端不需要安装以及升级维护 跨平台 较方便CS架构:Client/Server 客户端应用则需要每个客户端安装和升级 一种系统对应 ...

  8. 编写第一个 .NET 微服务

    介绍 本文的目的是:通过创建一个返回列表的简单服务,并在 Docker 容器中运行该服务,让您熟悉使用 .NET 创建微服务的构建过程. 安装 .NET SDK 要开始构建 .NET 应用程序,首先下 ...

  9. Zabbix housekeeper processes more than 75% busy

    原因分析 为了防止数据库持续增大,Zabbix有自动删除历史数据的机制,即housekeeper,而在频繁清理历史数据的时候,MySQL数据库可能出现性能降低的情况,此时就会告警. 一般来说,Zabb ...

  10. WEBAPI 增加身份验证

    1,在Webapi项目下添加如下引用: Microsoft.AspNet.WebApi.Owin Owin Microsoft.Owin.Host.SystemWeb Microsoft.Owin.S ...