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 ...
随机推荐
- express 配置 https 服务 ( 以阿里云服务器为例), 探索一周终于搞定
首先最重要的是 你要明白 https接口的接收或者发送 的形式 是 https://域名:端口号 而不是 https://ip:端口号 一,首先,去阿里云注册免费ssl证书 1,在搜索框 ...
- python 字典复制(存疑)
import copy x = {'a':1,'b':[2,3,4]} y = x.copy() z = copy.deepcopy(x) print(x) print(y) print(z) pri ...
- Java Math.round()函数小结
Math类中提供了三个与取整有关的方法:ceil,floor,round,这些方法的作用于它们的英文名称的含义相对应,例如:ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(1 ...
- windows下 RN 环境搭建
01.安装 Android Studio 02.NodeJs 03.Python204.JDK 05.安装Genymotion模拟器06.java 环境配置07.andriud sdk 配置08.An ...
- 036、Java中三目运算符的使用
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- SpringBoot-集成通用mapper
SpringBoot-集成通用mapper SpringBoot-集成通用mapper 我们在SpringBoot中整合了MyBatis,但是大量重复的增删改查还是很头疼的问题,MyBatis也给 ...
- 微信小程序学习开发笔记
首先注册小程序开账号,下载开发工具之后,先啃官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ ,把小程序的基本的代码框架 ...
- poj 1027 Ignatius and the Princess II全排列
Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ( ...
- chatdet用法
1. 下载chardet 2. 在命令提示符里转到chardet的存放目录,执行python setup.py install 3. 在代码中用 import chardet 导入模块 4. 用法:c ...
- P1006 换个格式输出整数
这道题相较于上一题来说就简单了许多.看题. 怎么感觉这道题有点类似P1002写出这个数.流程差不多,思路大致是先求出每一位上的数,然后根据 百十个 的顺序输出结果.题目比较简单,不做赘述,贴代码 代码 ...