Spring(3):AOP面向切面编程
一,AOP介绍
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
1,主要功能
日志记录,性能统计,安全控制,事务处理,异常处理等等
2,主要意图
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码
3,AOP在Spring中的作用
提供声明式事务;允许用户自定义切面
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
切面(ASPECT) | 横切关注点 被模块化 的特殊对象,即,它是一个类 |
通知(Advice) | 切面必须要完成的工作。即,它是类中的一个方法 |
目标(Target) | 被通知对象 |
代理(Proxy) | 向目标对象应用通知之后创建的对象 |
切入点(PointCut) | 切面通知 执行的 “地点”的定义 |
连接点(JointPoint) | 与切入点匹配的执行点 |
二,使用SpringAPI实现AOP
1,接口(User)

- 1 //抽象角色
- 2 public interface User {
- 3
- 4 public void show();
- 5
- 6 }

2,实现类(UserImpl)

- 1 //真实角色
- 2 public class UserImpl implements User{
- 3
- 4 public void show() {
- 5 System.out.println("这是一个show方法");
- 6 }
- 7
- 8 }

3,定义日志增加类实现
1.Log

- 1 import org.springframework.aop.MethodBeforeAdvice;
- 2 import java.lang.reflect.Method;
- 3
- 4 public class Log implements MethodBeforeAdvice {
- 5
- 6 //method:被调用目标对象的方法
- 7 //args:要被调用的方法的参数
- 8 //target:被调用的目标对象
- 9 public void before(Method method, Object[] args, Object target) throws Throwable {
- 10 System.out.println("目标对象:"+target.getClass().getName()+"的"
- 11 +method.getName()+"方法被执行了");
- 12 }
- 13 }

2.AfterLog

- 1 import org.springframework.aop.AfterReturningAdvice;
- 2 import java.lang.reflect.Method;
- 3
- 4 public class AfterLog implements AfterReturningAdvice {
- 5
- 6 //returnValue : 返回值
- 7 //method : 被调用目标对象的方法
- 8 //args : 要被调用的方法的参数
- 9 //target : 被调用的目标对象
- 10
- 11 public void afterReturning(Object returnValue, Method method,
- 12 Object[] args, Object target) throws Throwable {
- 13 System.out.println("执行了目标对象:"+target.getClass().getName()+"的"
- 14 +method.getName()+"方法,返回值:"+returnValue);
- 15 }
- 16
- 17 }

4,编写Spring核心配置文件(logbeans.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="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
- 10 <!--注册bean-->
- 11 <bean id="User" class="service.UserImpl"/>
- 12
- 13 <!--注册日志的bean-->
- 14 <bean id="Log" class="log.Log"/>
- 15 <bean id="AfterLog" class="log.AfterLog"/>
- 16
- 17 <!--使用spring的AOP切入-->
- 18 <aop:config>
- 19 <!--切入点-->
- 20 <aop:pointcut id="pointcut" expression="execution(* service.UserImpl.*(..))"/>
- 21 <!--执行通知,增强-->
- 22 <aop:advisor advice-ref="Log" pointcut-ref="pointcut"/>
- 23 <aop:advisor advice-ref="AfterLog" pointcut-ref="pointcut"/>
- 24 </aop:config>
- 25
- 26 </beans>

【注意点】
5,编写测试类(AopTest)

- 1 public class AopTest {
- 2 @Test
- 3 public void Test01(){
- 4 ClassPathXmlApplicationContext context =
- 5 new ClassPathXmlApplicationContext("logbeans.xml");
- 6 User user = (User) context.getBean("User");
- 7
- 8 user.show();
- 9 }
- 10 }

【注意点:测试时需要导入AOP的包在你的pom.xml中】
- 1 <dependency>
- 2 <groupId>org.aspectj</groupId>
- 3 <artifactId>aspectjweaver</artifactId>
- 4 <version>1.8.9</version>
- 5 </dependency>
6,运行结果
三,自定义类实现AOP
和使用SpringAPI实现AOP一样,先要建立抽象角色和真实角色,我们这里的接口与实体类和前面一样
1,自定一个Aop增强类:也就是所谓的切面

- 1 public class Diy {
- 2
- 3 public void before(){
- 4 System.out.println("show方法执行前");
- 5 }
- 6
- 7 public void after(){
- 8 System.out.println("show方法执行后");
- 9 }
- 10 }

2,配置文件(diybeans.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="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
- 10 <!--注册bean-->
- 11 <bean id="User" class="service.UserImpl"/>
- 12
- 13 <!--自定义的AOP增强类-->
- 14 <bean id="Diy" class="diy.Diy"/>
- 15
- 16 <!--编写aop配置文件-->
- 17 <aop:config>
- 18
- 19 <!--切面-->
- 20 <aop:aspect ref="Diy">
- 21 <!--切入点-->
- 22 <aop:pointcut id="diyPointCut" expression="execution(* service.UserImpl.*(..))"/>
- 23 <aop:before method="before" pointcut-ref="diyPointCut"/>
- 24 <aop:after method="after" pointcut-ref="diyPointCut"/>
- 25 </aop:aspect>
- 26
- 27 </aop:config>
- 28
- 29 </beans>

3,测试类

- 1 public class AopTest {
- 2 @Test
- 3 public void Test02(){
- 4 ClassPathXmlApplicationContext context =
- 5 new ClassPathXmlApplicationContext("diybeans.xml");
- 6 User user = (User) context.getBean("User");
- 7
- 8 user.show();
- 9 }
- 10 }

4,运行结果
四,使用注解实现AOP
接口和实体类不变
1,编写AOP增强类

- 1 @Aspect
- 2 public class Anno {
- 3
- 4 @Before("execution(* service.UserImpl.*(..))")
- 5 public void before(){
- 6 System.out.println("show方法执行前");
- 7 }
- 8
- 9 @After("execution(* service.UserImpl.*(..))")
- 10 public void after(){
- 11 System.out.println("show方法执行后");
- 12 }
- 13
- 14 }

【注意点】
2,配置文件(annobeans.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="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
- 10 <!--注册bean-->
- 11 <bean id="User" class="service.UserImpl"/>
- 12
- 13 <!--注册日志的bean-->
- 14 <bean id="Log" class="log.Log"/>
- 15 <bean id="AfterLog" class="log.AfterLog"/>
- 16
- 17 <!--使用spring的AOP切入-->
- 18 <aop:config>
- 19 <!--切入点-->
- 20 <aop:pointcut id="pointcut" expression="execution(* service.UserImpl.*(..))"/>
- 21 <!--执行通知,增强-->
- 22 <aop:advisor advice-ref="Log" pointcut-ref="pointcut"/>
- 23 <aop:advisor advice-ref="AfterLog" pointcut-ref="pointcut"/>
- 24 </aop:config>
- 25
- 26 </beans>

3,测试类

- 1 public class AopTest {
- 2 @Test
- 3 public void Test03(){
- 4 ClassPathXmlApplicationContext context =
- 5 new ClassPathXmlApplicationContext("annobeans.xml");
- 6 User user = (User) context.getBean("User");
- 7
- 8 user.show();
- 9 }
- 10 }

4,运行结果
五,AOP小结
- 本质就是动态代理
- 需要到一个包,用来进行aop织入的包: aspectjweaver
- 注意别遗漏了切面
- 三种实现AOP的方法
- 使用SpringAPI来实现AOP
- 使用自定义类来实现AOP
- 使用注解实现AOP
Spring(3):AOP面向切面编程的更多相关文章
- Spring:AOP面向切面编程
AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...
- Spring 08: AOP面向切面编程 + 手写AOP框架
核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...
- Spring框架 AOP面向切面编程(转)
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring的AOP面向切面编程
什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...
- spring:AOP面向切面编程02
参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...
- Spring注解 - AOP 面向切面编程
基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...
- Spring框架——AOP面向切面编程
简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...
- Spring之AOP(面向切面编程)_入门Demo
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可 ...
- 【spring源码学习】spring的AOP面向切面编程的实现解析
一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口 => ...
- 详解Spring框架AOP(面向切面编程)
最近在学习AOP,之前一直很不明白,什么是AOP?为什么要使用AOP,它有什么作用?学完之后有一点小小的感触和自己的理解,所以在这里呢就跟大家一起分享一下 AOP(Aspect-Oriented Pr ...
随机推荐
- Java-基础-HashMap
1. 简介 Java8 HashMap结构(数组 + 列表 + 红黑树)如图: 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和 ...
- for和while的区别及使用
for for的定义,()内的三段表达式,除了中间的必须产生布尔型,并未对其余两段有所限制,只要是表达式就可以了. //递增和递减 for(int i = 0;i < 100;i++) for ...
- url的hash和HTML5的history
url的hash和HTML5的history 第一种方法是改变url的hash值. **显示当前路径 : **location.href http://localhost:8080/# 切换路径: l ...
- 3D 穿梭效果?使用 UWP 也能搞定
昨天 ChokCoco 大佬搞了个 3D 穿梭效果出来,具体可见这里: 3D 穿梭效果?使用 CSS 轻松搞定 这个效果太神奇了,他还问我能不能用 WPF 搞出来,因为我完全没用过 WPF 的 3D, ...
- 什么?还在用delete删除数据《死磕MySQL系列 九》
系列文章 五.如何选择普通索引和唯一索引<死磕MySQL系列 五> 六.五分钟,让你明白MySQL是怎么选择索引<死磕MySQL系列 六> 七.字符串可以这样加索引,你知吗?& ...
- FZU ICPC 2020 寒假训练 4 —— 模拟(二)
P1056 排座椅 题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的 D 对同 ...
- 菜鸡的Java笔记 java数据库编程(JDBC)
java数据库编程(JDBC) 介绍 JDBC 的基本功能 content (内容) 现在几乎所有的项目开发过程之中都不可能离开数据库,所以在java ...
- 14-1-Unsupervised Learning ---dimension reduction
无监督学习(Unsupervised Learning)可以分为两种: 化繁为简 聚类(Clustering) 降维(Dimension Reduction) 无中生有(Generation) 所谓的 ...
- [hdu6134]Battlestation Operational
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mod 1000000007 4 #define N 1000005 ...
- [bzoj5415]归程
首先肯定要预处理出每一个点到1的最短路(别写spfa) 然后以海拔为边权,建一棵kruskal重构树 用倍增找到vi最后一个小于pi的祖先,然后在子树中取min(预处理) 1 #include< ...