[Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

前言: 
在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习.

一, AspectJ的概述:

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

Spring为了简化自身的AOP的开发,将AspectJ拿过来作为Spring自身一个AOP的开发.

二, Spring AspectJ开发实例

2.1 开发所需jar包

2.2 AspectJ 注解开发规范

2.2.1 @AspectJ提供不同的通知类型

@Before 前置通知,相当于BeforeAdvice
  在执行目标方法之前完成一个操作,获得到切入点信息.

@AfterReturning 后置通知,相当于AfterReturningAdvice

1 在目标方法执行之后完成一个操作,获得方法的返回值.
2
3 @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
4 public void afterReturing(Object result){
5     System.out.println("后置通知============"+result);
6 }

@Around 环绕通知,相当于MethodInterceptor

1 在目标方法执行的前和执行后完成一个操作,阻止目标方法执行.
2
3 @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
4 public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
5     System.out.println("环绕前通知==========");
6     Object obj = joinPoint.proceed();
7     System.out.println("环绕后通知==========");
8     return obj;
9 }


@AfterThrowing抛出通知,相当于ThrowAdvice

1 在目标方法出现异常的时候,完成一个操作.获得异常信息.
2
3 @AfterThrowing(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))",throwing="e")
4 public void afterThrowing(Throwable e){
5     System.out.println("异常抛出通知========="+e.getMessage());
6 }

@After 最终final通知,不管是否异常,该通知都会执行

1 在目标方法任何情况下都会执行的操作.相当于finally中的代码.
2
3 @After(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
4 public void after(){
5     System.out.println("最终通知===========");
6 }


2.2.2 通过配置启用@AspectJ切面

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:aop="http://www.springframework.org/schema/aop"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans.xsd
 7     http://www.springframework.org/schema/aop
 8     http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     <!-- 开启AspectJ自动代理-->
10     <aop:aspectj-autoproxy />
11 </beans>

2.2.3 在通知中通过value属性定义切点

通过execution函数,可以定义切点的方法切入
语法:
  execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如
  匹配所有类public方法 execution(public * *(..))
  匹配指定包下所有类方法 execution(* cn.itcast.dao.*(..)) 不包含子包
  execution(* cn.itcast.dao..*(..)) ..*表示包、子孙包下所有类
  匹配指定类所有方法 execution(* cn.itcast.service.UserService.*(..))
  匹配实现特定接口所有类方法 execution(* cn.itcast.dao.GenericDAO+.*(..))
  匹配所有save开头的方法 execution(* save*(..))

2.2.4 AspectJ的切入点:

1 统一管理切入点的表达式.
2 @Pointcut(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
3 private void myPointcut1(){} //这个类没有实际用途, 只是为了@Pointcut 注解


2.2.6 Aspect和Advisor的区别:

Advisor :传统的切面.传统切面一般都是由一个切入点和一个通知的组合.
Aspect :真正意义上的切面.由多个切入点和多个通知的组合.

2.3 Spring AspctJ 基于注解模式的开发
CustomerService.java:

1 public interface CustomerService {
2
3     public void save();
4     public Integer update();
5     public void delete();
6     public void find();
7 }

CustomerServiceImpl.java:

 1 public class CustomerServiceImpl implements CustomerService {
 2
 3     @Override
 4     public void save() {
 5         System.out.println("保存客户...");
 6     }
 7
 8     @Override
 9     public Integer update() {
10         System.out.println("修改客户...");
11         return 100;
12     }
13
14     @Override
15     public void delete() {
16         System.out.println("删除客户...");
17     }
18
19     @Override
20     public void find() {
21         System.out.println("查询客户...");
22         int d = 1 / 0;
23     }
24
25 }

MyAspectAnno.java:

 1 /**
 2  * 自定义切面类:
 3  *
 4  */
 5 @Aspect
 6 public class MyAspectAnno {
 7
 8     @Before(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.save(..))")
 9     public void before(JoinPoint joinPoint){
10         System.out.println("前置通知============"+joinPoint);
11     }
12
13     @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
14     public void afterReturing(Object result){
15         System.out.println("后置通知============"+result);
16     }
17
18     @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
19     public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
20         System.out.println("环绕前通知==========");
21         Object obj = joinPoint.proceed();
22         System.out.println("环绕后通知==========");
23         return obj;
24     }
25
26     @AfterThrowing(value="MyAspectAnno.myPointcut1()",throwing="e")
27     public void afterThrowing(Throwable e){
28         System.out.println("异常抛出通知========="+e.getMessage());
29     }
30
31     @After(value="MyAspectAnno.myPointcut1()")
32     public void after(){
33         System.out.println("最终通知===========");
34     }
35
36     @Pointcut(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.find(..))")
37     private void myPointcut1(){}
38 }

SpringDemo.java 测试类:

 1 @RunWith(SpringJUnit4ClassRunner.class)
 2 @ContextConfiguration("classpath:applicationContext.xml")
 3 public class SpringDemo1 {
 4
 5     @Resource(name = "customerService")
 6     private CustomerService customerService;
 7
 8     @Test
 9     public void demo1() {
10         customerService.save();
11         customerService.update();
12         customerService.delete();
13         customerService.find();
14     }
15 }

applicationContext.xml 配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:aop="http://www.springframework.org/schema/aop"
 5        xsi:schemaLocation="
 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 8
 9     <!-- 使用注解完成AOP的开发 -->
10     <aop:aspectj-autoproxy/>
11
12     <!-- 目标对象 -->
13     <bean id="customerService" class="cn.augmentum.aspectj.demo1.CustomerServiceImpl"/>
14
15     <!-- 配置切面 -->
16     <bean id="myAspectAnno" class="cn.augmentum.aspectj.demo1.MyAspectAnno"/>
17 </beans>

2.3 Spring AspctJ 基于xml模式的开发

OrderService.java:

 1 public class OrderService {
 2     public void save(){
 3         System.out.println("保存订单...");
 4     }
 5     public Integer update(){
 6         System.out.println("修改订单...");
 7         return 200;
 8     }
 9     public void delete(){
10         System.out.println("删除订单...");
11     }
12     public void find(){
13         System.out.println("查询订单...");
14         //int d = 1/ 0;
15     }
16 }

MyAspectXml.java:

 1 public class MyAspectXml {
 2
 3     public void before(){
 4         System.out.println("前置通知===========");
 5     }
 6
 7     public void afterReturing(Object result){
 8         System.out.println("后置通知==========="+result);
 9     }
10
11     public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
12         System.out.println("环绕前通知==========");
13         Object obj = joinPoint.proceed();
14         System.out.println("环绕后通知==========");
15         return obj;
16     }
17
18     public void afterThrowing(Throwable e){
19         System.out.println("异常抛出通知========"+e.getMessage());
20     }
21
22     public void after(){
23         System.out.println("最终通知==========");
24     }
25 }

SpringDemo.java 测试类:

 1 @RunWith(SpringJUnit4ClassRunner.class)
 2 @ContextConfiguration("classpath:applicationContext.xml")
 3 public class SpringDemo2 {
 4
 5     @Resource(name="orderService")
 6     private OrderService orderService;
 7
 8     @Test
 9     public void demo1(){
10         orderService.save();
11         orderService.update();
12         orderService.delete();
13         orderService.find();
14     }
15 }

applicationContext.xml 配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:aop="http://www.springframework.org/schema/aop"
 5        xsi:schemaLocation="
 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
 8
 9     <!-- 配置目标类 -->
10     <bean id="orderService" class="cn.augmentum.aspectj.demo2.OrderService"></bean>
11
12     <!-- 配置切面 -->
13     <bean id="myAspectXml" class="cn.augmentum.aspectj.demo2.MyAspectXml"></bean>
14
15     <!-- AOP的配置 -->
16     <aop:config>
17         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.save(..))" id="pointcut1"/>
18         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.update(..))" id="pointcut2"/>
19         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.delete(..))" id="pointcut3"/>
20         <aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.find(..))" id="pointcut4"/>
21         <aop:aspect ref="myAspectXml">
22             <aop:before method="before" pointcut-ref="pointcut1"/>
23             <aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"/>
24             <aop:around method="around" pointcut-ref="pointcut3"/>
25             <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
26             <aop:after method="after" pointcut-ref="pointcut4"/>
27         </aop:aspect>
28     </aop:config>
29 </beans>

OK. 到了这里Spring 基于AOP的开发也总结完了, 学习之路漫漫, 谨以此记录成长的过程!

 

 

 

 

 

 

时间: 2024-10-26 11:25:55

[Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.的相关文章

[Spring框架]Spring AOP基础入门总结一.

前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务

PHP基础入门(二)【PHP函数基础】

PHP基础入门(二)--函数基础 了解 PHP基础入门详解(一) 后,给大家分享一下PHP的函数基础. 这部分主要讲的就是: 函数的声明与使用.PHP中变量的作用域.静态变量.函数的参数传递.变量函数.回调函数.匿名函数.include&require.PHP闭包 PHP的函数基础↓↓↓ 一.函数的声明与使用 1.标识符:程序中的变量名,属性名,方法名,函数名,类名统称为标识符: ① 标识符的命名要求:  只要是标识符,命名就只有字母.数字.下划线组成,开头不能是数字: ② 标识符的命名规范:

Android基础入门教程——3.2 基于回调的事件处理机制

Android基础入门教程--3.2 基于回调的事件处理机制 标签(空格分隔): Android基础入门教程 本节引言 在3.1中我们对Android中的一个事件处理机制--基于监听的事件处理机制进行了学习,简单的说就是 为我们的事件源(组件)添加一个监听器,然后当用户触发了事件后,交给监听器去处理,根据不同的事件 执行不同的操作;那么基于回调的事件处理机制又是什么样的原理呢?好吧,还有一个问题:你知道 什么是方法回调吗?知道吗?相信很多朋友都是了解,但又说不出来吧!好了,带着这些疑问我们 对a

Android基础入门教程——1.2.1 使用Eclipse + ADT + SDK开发Android APP

Android基础入门教程--1.2.1 使用Eclipse + ADT + SDK开发Android APP 标签(空格分隔): Android基础入门教程 1.前言 这里我们有两条路可以选,直接使用封装好的用于开发Android的ADT Bundle,或者自己进行配置 因为谷歌已经放弃了ADT的更新,官网上也取消的下载链接,这里提供谷歌放弃更新前最新版本的 ADT Bundle供大家下载! 2.直接使用打包好的Eclipse 32位版:adt-bundle-windows-x86-20140

利用基于@AspectJ的AOP实现权限控制

一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理解为在系统中,我们需要很多次重复实现的功能.比如计算某个方法运行了多少毫秒,判断用户是不是具有访问权限,用户是否已登录,数据的事务处理,日志记录等等. AOP的术语 连接点(Joinpoint) 程序执行的某个特殊位置:比如类开始初始化前,类初始化后,某个方法调用前,调用后等. 连接点 可 以 理解

Spring框架的一些基础知识

Spring 框架 Spring 框架是一个分层架构,由 7 个定义良好的模块组成.Spring 模块构建在核心容器之上,核心容器定义了创建.配置和管理 bean 的方式,如图 1 所示. 图 1. Spring 框架的 7 个模块 组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现.每个模块的功能如下: 核心容器:核心容器提供 Spring 框架的基本功能.核心容器的主要组件是 BeanFactory,它是工厂模式的实现.BeanFactory 使用控

Spring4- 01 - Spring框架简介及官方压缩包目录介绍- Spring IoC 的概念 - Spring hello world环境搭建

一. Spring 框架简介及官方压缩包目录介绍 主要发明者:Rod Johnson 轮子理论推崇者: 2.1 轮子理论:不用重复发明轮子. 2.2 IT 行业:直接使用写好的代码. Spring 框架宗旨:不重新发明技术,让原有技术使用起来更加方便. Spring 几大核心功能 4.1 IoC/DI控制反转/依赖注入 4.2 AOP面向切面编程 4.3 声明式事务. Spring 框架runtime 5.1 test: spring 提供测试功能 5.2 Core Container:核心容器

Spring Boot 2.x基础教程:使用Spring Data JPA访问MySQL

在数据访问这章的第一篇文章<Spring中使用JdbcTemplate访问数据库> 中,我们已经介绍了如何使用Spring Boot中最基本的jdbc模块来实现关系型数据库的数据读写操作.那么结合Web开发一章的内容,我们就可以利用JDBC模块与Web模块的功能,综合着使用来完成一个适用于很多简单应用场景的后端应用了. 然而当我们有一定的开发经验之后,不难发现,在实际开发过程中,对数据库的操作大多可以归结为:"增删改查".就最为普遍的单表操作而言,除了表和字段不同外,语句几

【SSH三大框架】Hibernate基础第十二篇:load()懒加载分析以及一对一、一对多、多对一、多对多懒加载的分析

一.懒加载的定义: 懒加载:在WEB应用程序中,经常会需要查询数据库,系统的响应速度在很大程度上是与数据库交互的响应.因此,如果能够优化与数据库的交互速度,则能够大大提高WEB应用的响应速度. 例如:当有一个Student类和一个Teacher类.当我们加载一个学生的所有信息,包括:学号,姓名等属性后,此时Student类中的Teacher类型的属性为null,当我们需要知道这个Student对应的Teacher属性的时候,我们才去加载这个Teacher对象. 如果,我们只需要知道学生信息,我们