Spring AOP复习
最近在翻《Spring In Action》Spring 实战这本书,重新了解了一下AOP的概念和思想并写了一个小Demo示例,记录在这里:
环境:intelliJ IDEA 2018、MAVEN管理依赖
一:项目的POM文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.cmhit.springinaction</groupId>
<artifactId>Chapter3</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies> </project>
pom.xml
二:创建包来容纳用到的类文件:
三:创建接口类Performance,该类仅有一个perform方法:
package concert; public interface Performance {
public void perform();
}
Performance.java
四:创建接口的实现类Movie
package concert; import org.springframework.stereotype.Component; @Component
public class Movie implements Performance {
public void perform(){
System.out.println("The movie is showing");
};
}
Movie.java
五:定义一个“观众”切面:
package concert; import org.aspectj.lang.annotation.*; @Aspect
public class Audience {
@Pointcut("execution( * concert.Performance.perform(..))")
public void performance(){} @Before("performance()")
public void silenceCellPhones(){
System.out.println("Silencing cell phones");
} @Before("performance()")
public void takeSeats(){
System.out.println("Taking seats");
} @AfterReturning("performance()")
public void applause(){
System.out.println("CLAP CLAP CLAP");
} @AfterThrowing("performance()")
public void demandRefund(){
System.out.println("Demanding a refund");
}
}
Audience.java
六:至此,基本的类都已经建立完毕了,下面创建配置类将它们装配起来:
package concert; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "concert")
public class appConfig {
@Bean
public Performance movie() {
return new Movie();
} @Bean
public Audience audience(){
return new Audience();
}
}
appConfig
七:在test目录下面建立相同的package,并创建测试类:
package concert; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = appConfig.class)
public class TestConcert {
@Autowired
private Performance perform; @Test
public void test01(){
perform.perform();
}
}
TestConcert
八:测试运行结果:
九:根据上面的demo,再次加深理解AOP的几个概念:通知、连接点、切点、切面、织入
通知:通知定义了切面要完成的工作以及在什么时候使用,上面的demo中,表演前的手机静音,表演前观众入座,表演成功结束后的鼓掌,表演失败后观众要求退票,这其中的每一项都是通知,通知可以分为前置通知(目标方法调用前执行),后置通知(方法完成后执行,且不管方法的输出是什么),返回通知(方法成功执行后调用通知),异常通知(方法执行发生异常时调用通知),环绕通知(通知包裹了被通知的方法,效果类似方法调用前后均调用,但是环绕通知可以将所有的通知方法放在一起);
连接点:连接点是应用执行过程中能插入到切面的点,这个点可以是方法被调用,抛出异常或者是属性被修改,切面的代码就是利用这些连接点将代码插入到应用程序的正常流程中,上面demo中的perform方法就是一个连接点;
切点:应用程序中存在数以千计的连接点,我们的切面程序代码不一定要插入到所有的连接点中,那些切面织入的连接点集合就是切点。
切面:切面是通知和切点的集合,即切面描述了需要做什么工作(手机静音、就坐、鼓掌、退票),在什么时候工作(perform方法执行前还是执行后,还是发生异常时),在哪些地方执行工作。
织入:将切面在指定的连接点织入到目标对象中的过程就是织入,织入的基本原理是创建原对象的代理对象,所有在原对象上的方法调用均会被代理对象拦截(代理类封装了目标类),在执行完切面逻辑代码后,再将调用转给真正的目标bean。
补充:可以使用环绕通知重写上面的audience类:
package concert; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class Audience { @Pointcut("execution( * concert.Performance.perform(..))")
public void performance(){} @Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp){
try {
System.out.println("Silencing cell phones");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP");
}catch (Throwable e){
System.out.println("Demanding a refund");
}
}
}
Audience.java
执行的效果和上面是一样的,代码中的ProceedingJoinPoint对象用来控制被通知方法的调用:jp.proceed(),如果不调用这个方法,可以实现阻塞被通知方法(performance)的调用,而且可以反复调用jp.proceed(),相当于反复调用perform()方法。
Spring AOP复习的更多相关文章
- Spring AOP 复习
Aspect Oriented Programming 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降 ...
- Spring技术内幕:Spring AOP的实现原理(二)
**二.AOP的设计与实现 1.JVM的动态代理特性** 在Spring AOP实现中, 使用的核心技术时动态代理.而这样的动态代理实际上是JDK的一个特性.通过JDK的动态代理特性,能够为随意Jav ...
- Spring AOP 和 AspectJ
现如今有许多个可用的 AOP 库,使用这些库需要能够回答以下问题: 是否与现有的或新的应用程序兼容? 在哪里可以使用 AOP ? 如何迅速与应用程序集成? 性能开销是多少? 在本文中,我们将回答这些问 ...
- Spring知识点复习
Spring知识点复习 一.专业术语 侵入式设计 引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类.如:Struts框架 非侵入式设计 引入框架,对现有的类结构没有影响.如:Hiberna ...
- 运用Spring Aop,一个注解实现日志记录
运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- spring aop
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
- spring aop注解方式与xml方式配置
注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...
随机推荐
- java基础知识(1)
Java包 包主要用来对类和接口进行分类.当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类. Import语句 在Java中,如果给出一个完整的限定名,包括包名.类名,那么J ...
- Combobox出现System.Data.DataRowView的原因
这种情况多次遇到.有时候明明完全相同的代码,在不同的场景运行却是两种结果, 其中一种坏的结果就是 comboBox所有的项都显示为System.Data.DataRowView 今天仔研究了一下,应该 ...
- BFPRT(中位数的中位数算法)
BFPRT(中位数的中位数算法) 类似于快排,但是划分区间的策略不一样. 分组,组内排序: 取出每组的中位数组成一个数组,再取这个数组的中位数: 以取出的中位数作为partition的轴.
- python 安装opendr 报错OSMesa
### 报错/ERROR: ```opendr/contexts/OSMesa/include/GL/glext.h:5794:21: note: expected ‘const GLchar ** ...
- 小米手机收到升级鸿蒙OS提示?官方回应
虽然尚未得到官方确认,但华为“鸿蒙”OS已经成为网络热门话题,在机圈引发热议. 本周,互联网上出现了显示为MIUI 10手机被锁定,屏幕上出现“小米将于2020年9月15日全面停止服务,届时您所有设备 ...
- netty权威指南学习笔记四——TCP粘包/拆包之粘包问题解决
发生了粘包,我们需要将其清晰的进行拆包处理,这里采用LineBasedFrameDecoder来解决 LineBasedFrameDecoder的工作原理是它依次遍历ByteBuf中的可读字节,判断看 ...
- 查看linux硬件的信息
cpu: cat /proc/cpuinfo 内存: cat /proc/meminfo 查看内存使用情况: free -m -m指以M的单位显示 查看硬盘使用情况: df -h ...
- 获得spring
这里 手动下载 各版本的发行包 这里是 官方项目地址 这里是在 GitHub上托管源代码 的地方 已知spring依赖的其他jar commons-logging-1[1].0.4.jar
- Azure Container Registry-基于开源 Docker Registry 的专用 Docker 注册表服务
本文语雀知识库:https://www.yuque.com/seanyu/azure/acr 概述 Azure 容器注册表(Azrue Container Registry,简称ACR)是 Azure ...
- 了解facade设计模式
Facade模式 Facade模式要求一个子系统的外部与其内部的通信必须通过一个统一的Facade对象进行.Facade模式提供一个高层次的接口,使得子系统更易于使用. 就如同医院的接待员一样,Fac ...