spring AOP 编程--AspectJ注解方式 (4)

1. AOP 简介

AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.

AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.

在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.

AOP 的好处:

---每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级

---业务模块更简洁, 只包含核心业务代码.

2. AOP的术语和图形表达

切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象

通知(Advice): 切面必须要完成的工作

目标(Target): 被通知的对象

代理(Proxy): 向目标对象应用通知之后创建的对象

连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置

切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。

通知:

  前置通知(before advice):在切入点之前执行。

  后置通知(after returning advice):在切入点执行完成后,执行通知。无论是否抛出异常,都会执行。在后置通知中不能访问方法返回的结果

  环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。

  异常通知(after throwing advice):在切入点抛出异常后,执行通知。

方式一、aspectj注解

1、需要引入一个

2、ArithmeticCalculator.java

1 package com.proc;
2
3 public interface ArithmeticCalculator {
4     int add(int i, int j);
5     int sub(int i, int j);
6
7     int mul(int i, int j);
8     int div(int i, int j);
9 }

3、ArithmeticCalculatorImpl.java

 1 package com.proc;
 2 import org.springframework.stereotype.Component;
 3
 4
 5 @Component("arithmeticCalculator")
 6 public class ArithmeticCalculatorImpl implements ArithmeticCalculator{
 7     public int add(int i, int j) {
 8         int result = i + j;
 9         return result;
10     }
11
12     public int sub(int i, int j) {
13         int result = i - j;
14         return result;
15     }
16
17     public int mul(int i, int j) {
18         int result = i * j;
19         return result;
20     }
21
22     public int div(int i, int j) {
23         int result = i / j;
24         return result;
25     }
26 }

4、LoggingAspect.java

 1 package com.proc;
 2
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.annotation.Aspect;
 5 import org.aspectj.lang.annotation.Before;
 6 import org.springframework.stereotype.Component;
 7
 8 @Aspect
 9 @Component
10 public class LoggingAspect {
11
12     @Before("execution(* *.*(int,int))")
13     public void beforeMethod(JoinPoint point){
14         System.out.println("正在执行方法: "+point.getSignature().getName());
15     }
16 }

  这是一个日志切面类,该类首先是一个IoC中的bean,通过@Component将bean交个容器管理,然后@Aspect声明这是一个切面。

  @Before是通知时机,表示在调用方法之前通知。 里面字符串格式为execution (访问修饰符 返回类型 包名.类名.方法名(参数类型...))。

  beforeMethod是定一个的一个切面执行的方法,方法名可以任意指定。可以不带参数,也可以指定一个JoinPoint连接点的参数。

配置

1 <context:component-scan base-package="com.proc" />
2 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

  aop:aspectj-autoproxy:使得@Aspect注解生效

测试代码:

1 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2 ArithmeticCalculator calc=(ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
3 System.out.println(calc.add(3, 5));
4 System.out.println(calc.sub(3, 5));
5 System.out.println(calc.mul(6, 2));
6 System.out.println(calc.div(6, 2)); 

输出结果

正在执行方法add
8
正在执行方法sub
-2
正在执行方法mul
12
正在执行方法div
3

上面方法是用的前置通知。下面我们讲解一下后置通知、返回通知、异常通知和环绕通知

☆后置通知

  后置通知无论方法是否抛出异常,都会执行。在后置通知中不能访问返回结果,因为可能会出现异常,就没有返回值

1 @After("execution(* *.*(int,int))")
2 public void afterMethod(JoinPoint point){
3     System.out.println("方法执行结束: "+point.getSignature().getName());
4 }

☆返回通知

  当方法有异常时,不会执行返回通知,只有在方法正常执行结束才能够执行返回通知。在结果通知中用参数returning来指定接收返回结果对象的名称,直接传递给下面方法中对应的参数

1 @AfterReturning(value="execution(* *.*(int,int))",returning="retVal")
2 public void afterReturningMethod(JoinPoint point,Object retVal){
3     System.out.println("方法: "+point.getSignature().getName()+"执行结果为:"+retVal);
4 }

☆异常通知

  当方法有异常时,才会执行返回异常通知

1 @AfterThrowing(value="execution(* *.*(int,int))",throwing="ex")
2 public void afterThrowingMethod(JoinPoint point,Exception ex){
3     System.out.println("执行方法: "+point.getSignature().getName()+"出现了异常:"+ex.getMessage());
4 }

【注意】:在指定异常类型时,只能捕获到该类型或子类型的异常。比如指定NullPointerException异常,就只能捕获空指针异常,所以,我们可以指定为异常的父类型。

☆环绕通知

  环绕通知是一个比较强大,但相对复杂一点的通知,我们通常不使用

 1 @Around("execution(* *.*(int,int))")
 2 public Object aroundMethod(ProceedingJoinPoint point){
 3
 4     System.out.println("环绕通知: "+point.getSignature().getName());
 5     Object result=null;
 6     //这里相当于前置通知
 7     try {
 8         //执行方法
 9         result= point.proceed();
10         //这里相当于结果通知
11     } catch (Throwable e) {
12         //这里相当于异常通知
13         e.printStackTrace();
14
15     }
16     //这里相当于后置通知
17     System.out.println("环绕通知: "+point.getSignature().getName());
18     return result;
19 }

【注意】:环绕通知要求有一个返回值point.proceed()执行方法,并提供一个返回值

原文地址:https://www.cnblogs.com/weiqingfeng/p/9497975.html

时间: 2024-10-27 18:29:26

spring AOP 编程--AspectJ注解方式 (4)的相关文章

【Spring】—AOP之AspectJ注解方式实现声明式事务管理

前言 这回来说下注解方式的声明式事务管理. 正文 Demo 1.引入相关的jar包这里写图片描述 2.引入AOP约束<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/con

初步学习Spring Aop使用之注解方式

前言: 这里就主要演示Spring中Aop使用注解是怎么使用,如果需要了解更多Aop相关概念,可查看相关资料的介绍 一.项目目录 [标记文件为主要文件] 二.各个文件的代码 AopServer.java [编写切点的文件,就是一些需要被修饰的业务处理] package aop; import org.springframework.stereotype.Service; @Service public class AopServer { public void add() { System.ou

spring AOP解析之注解方式详解

命名空间处理器是AopNamespaceHandler,我们可以看到这里注册了几个解析器,第一个我们知道是xml形式的解析,接下来我们看AspectJAutoProxyBeanDefinitionParser解析器

SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

AOP(Aspect Oriented Programming).是面向切面编程的技术.AOP基于IoC基础.是对OOP的故意补充. AOP之所以能得到广泛应用,主要是由于它将应用系统拆分分了2个部分:核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的切面Crosscutting enterprise concerns.比如,全部大中型应用都要涉及到的持久化管理(Persistent).事务管理(Transaction Management).权限管理(P

spring之aop编程——基于注解、xml配置文件方式

AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充.spring中AOP的配置方式有2种方式:xml配置和AspectJ注解方式. 一.xml配置的方式: 1.service接口和服务类: package cn.edu.nuc.SpringTest.service; public interface DemoService { public String sayHello(String name) ; } packa

比较分析 Spring AOP 和 AspectJ 之间的差别

面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Spring AOP和AspectJ.这里将会帮助你基于一些关键信息,为你的项目选择正确的技术. Spring AOP不同于大多数其他AOP框架.Spring AOP的目的并不是为了提供最完整的AOP实现(虽然Spring AOP具有相当的能力):而是为了要帮助解决企业应用中的常见问题,提供一个AOP实

Spring AOP With AspectJ

一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP,当然这里面的区别我会重新写一篇文章讲解,这里面提一下就是想告诉大家,不一定要使用AOP,个人感觉用Filter和Interceptor实现的更方便简单一点. 二.AOP 准备 在spring框架下,你还需要添加aspectjrt,aspectjweaver和cglib 的相关jar包,maven项目的pom.

七 Spring的IOC的注解方式

Spring的IOC的注解方式入门 创建web项目,引入相应的jar包 除了IOC的6个包,还需要AOP的包 引入Spring配置文件 创建applicationContext.xml 引入约束:使用注解开发引入context约束 file:///D:/Hibernate/Spring/spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html 创建接口和实现类: 配置Spr

Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx":意思是返回到某个JSP页面上 如果想在此Action中跳转到另一个Action中怎样做呢? return "redirect://.do?" 例如: @RequestMapping(params = "action=delete") public String del