Spring 一二事(9) - xml 形式的 AOP

简介: AOP在spring中是非常重要的一个 在切面类中,有5种通知类型: aop:before  前置通知 aop:after-returning  后置通知 aop:after  最终通知 aop:after-throwing  异常通知 aop:around  环绕通知 1   ...

AOP在spring中是非常重要的一个

在切面类中,有5种通知类型:

aop:before  前置通知

aop:after-returning  后置通知

aop:after  最终通知

aop:after-throwing  异常通知

aop:around  环绕通知

 1    <bean id="personDAO" class="com.lee.spring002.aop.xml.PersonDAOImpl"></bean>
 2     <bean id="transaction" class="com.lee.spring002.aop.xml.Transaction"></bean>
 3     
 4     <aop:config >
 5         <!-- 切入点表达式,作用:确定目标类 -->
 6         <!-- spring 会自动检测这个表达式下的类是否是切面,如果是,则不会包含进来 -->
 7         <aop:pointcut expression="execution(* com.lee.spring002.aop.xml.PersonDAOImpl.*(..))" id="perform"/>
 8         <!-- ref 指向切面 -->
 9         <aop:aspect ref="transaction">
10             <!-- 前置通知 -->
11             <aop:before method="beginTransaction" pointcut-ref="perform"/>
12             
13             <!-- 
14                 后置通知
15                     可以获取目标方法的返回值(前置方法获取不到)
16                     如果目标方法抛出异常,后置通知则不会继续执行
17              -->
18             <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
19             
20             <!-- 
21                 最终通知
22                     无论目标方法是否抛出异常都将执行此方法
23              -->
24              <aop:after method="finallyDisplay" pointcut-ref="perform"/>
25              
26              <!-- 
27                  异常通知
28               -->
29               <aop:after-throwing method="exception" pointcut-ref="perform" throwing="content"/>
30               
31               <!-- 
32                   环绕通知
33                       能控制目标方法能否执行
34                       前置通知和后置通知能在目标方法的前后加代码,但是不能控制方法的执行
35                -->
36                <aop:around method="arround" pointcut-ref="perform"/>
37         </aop:aspect>
38     </aop:config>

关于切面的表达式简单说一下:

  • 任意公共方法的执行:
    execution(public * *(..))
  • 任何一个名字以“set”开始的方法的执行:
    execution(* set*(..))
  • AccountService接口定义的任意方法的执行:
    execution(* com.xyz.service.AccountService.*(..))
  • 在service包中定义的任意方法的执行:
    execution(* com.xyz.service.*.*(..))
  • 在service包或其子包中定义的任意方法的执行:
    execution(* com.xyz.service..*.*(..))

 

IPersonDAO.java

1 package com.lee.spring002.aop.xml;
2 
3 public interface IPersonDAO {
4     public String savePerson();
5 }

PersonDAOImpl.java

 1 package com.lee.spring002.aop.xml;
 2 
 3 public class PersonDAOImpl implements IPersonDAO {
 4 
 5     @Override
 6     public String savePerson() {
 7         System.out.println("PersonDAOImpl - savePerson()");
 8         
 9 //        int a = 1 / 0;
10         
11         return "save successfully";
12     }
13 
14 }

Transaction.java

 

 1 package com.lee.spring002.aop.xml;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 /**
 7  * 这是个切面
 8  * 
 9  * @author leechenxiang
10  * @date 2016年1月12日
11  *
12  */
13 public class Transaction {
14     
15     public void beginTransaction(JoinPoint jp) {
16         System.out.println("连接点名称: " + jp.getSignature().getName());
17         System.out.println("目标类名称: " + jp.getTarget().getClass());
18         System.out.println("Begin transaction...");
19     }
20     
21     /**
22      * 
23      * @param jp
24      * @param val 目标方法返回值,要与returning对应 
25      */
26     public void commit(JoinPoint jp, Object val) {
27         System.out.println("Transaction commit...");
28         
29         System.out.println("returning: " + val.toString());
30     } 
31     
32     public void finallyDisplay() {
33         System.out.println("finally...");
34     }
35     
36     public void exception(JoinPoint jp, Throwable content) {
37         System.out.println("exception: " + content);
38         System.out.println("exception: " + content.getMessage());
39     }
40     
41     public void arround(ProceedingJoinPoint pjp) throws Throwable {
42         System.out.println("arround...");
43         pjp.proceed();    // 调用目标方法,如果这行不写,则目标方法不执行
44     }
45 }

测试:

 1 package com.lee.spring002.aop.xml;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 public class TransactionTest {
 8 
 9     /**
10      * 原理:
11      *    1、当spring容器启动的时候,加载两个bean,对两个bean进行实例化
12      *    2、当spring容器对配置文件解析到<aop:config>的时候
13      *    3、把切入点表达式解析出来,按照切入点表达式匹配spring容器内容的bean
14      *    4、如果匹配成功,则为该bean创建代理对象
15      *    5、当客户端利用context.getBean获取一个对象时,如果该对象有代理对象,则返回代理对象
16      *         如果没有代理对象,则返回对象本身
17      */
18     @Test
19     public void testPerson() {
20         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
21         IPersonDAO personDAO = (IPersonDAO)context.getBean("personDAO");
22         personDAO.savePerson();
23     }
24 
25 }

 

github地址:https://github.com/leechenxiang/maven-spring002-aop

 

 

相关文章
|
7天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
1天前
|
XML Java 数据格式
Spring高手之路18——从XML配置角度理解Spring AOP
本文是全面解析面向切面编程的实践指南。通过深入讲解切面、连接点、通知等关键概念,以及通过XML配置实现Spring AOP的步骤。
21 6
Spring高手之路18——从XML配置角度理解Spring AOP
|
7天前
|
XML Java 数据格式
Spring使用AOP 的其他方式
Spring使用AOP 的其他方式
15 2
|
7天前
|
XML Java 数据格式
Spring 项目如何使用AOP
Spring 项目如何使用AOP
20 2
|
12天前
|
Java 开发者 Spring
Spring AOP的切点是通过使用AspectJ的切点表达式语言来定义的。
【5月更文挑战第1天】Spring AOP的切点是通过使用AspectJ的切点表达式语言来定义的。
24 5
|
12天前
|
XML Java 数据格式
Spring AOP
【5月更文挑战第1天】Spring AOP
27 5
|
3月前
|
Java 数据库连接 应用服务中间件
Spring5源码(39)-Aop事物管理简介及编程式事物实现
Spring5源码(39)-Aop事物管理简介及编程式事物实现
26 0
|
4月前
AOP&面向切面编程
AOP&面向切面编程
56 0
|
4月前
|
Java 程序员 Maven
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
|
4月前
|
数据库
AOP(面向切面编程)的基本概念和原理
AOP(面向切面编程)的基本概念和原理
91 0