一,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面向切面编程的更多相关文章

  1. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  2. Spring 08: AOP面向切面编程 + 手写AOP框架

    核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...

  3. Spring框架 AOP面向切面编程(转)

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  4. Spring的AOP面向切面编程

    什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: ...

  5. spring:AOP面向切面编程02

    参考: https://blog.csdn.net/jeffleo/article/details/54136904 一.AOP的核心概念AOP(Aspect Oriented Programming ...

  6. Spring注解 - AOP 面向切面编程

    基本概念: AOP:Aspect Oriented Programming,即面向切面编程 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式 前置通知(@Before):在目标 ...

  7. Spring框架——AOP面向切面编程

    简介 AOP练习 使用动态代理解决问题 Spring AOP 用AspectJ注解声明切面 前置后置通知 利用方法签名编写AspectJ切入点表达式 指定切面的优先级 基于XML的配置声明切面 Spr ...

  8. Spring之AOP(面向切面编程)_入门Demo

    AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可 ...

  9. 【spring源码学习】spring的AOP面向切面编程的实现解析

    一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口  => ...

  10. 详解Spring框架AOP(面向切面编程)

    最近在学习AOP,之前一直很不明白,什么是AOP?为什么要使用AOP,它有什么作用?学完之后有一点小小的感触和自己的理解,所以在这里呢就跟大家一起分享一下 AOP(Aspect-Oriented Pr ...

随机推荐

  1. 攻防世界 WEB 高手进阶区 csaw-ctf-2016-quals mfw Writeup

    攻防世界 WEB 高手进阶区 csaw-ctf-2016-quals mfw Writeup 题目介绍 题目考点 PHP代码审计 git源码泄露 Writeup 进入题目,点击一番,发现可能出现git ...

  2. 你会用ES6,那倒是用啊!

    leader的吐槽大会(在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已.) ps:ES5之后的JS语法统称ES6!!! 一.关于 ...

  3. Java String 转成 二位数组

    ... package str; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; impo ...

  4. 学不懂Netty?看不懂源码?不存在的,这篇文章手把手带你阅读Netty源码!

    阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...

  5. java-TCP协议发送和接收数据

    TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...

  6. C代码

    #include<stdio.h>#include<stdlib.h>void main(){    char    ch, file_name1[20], file_name ...

  7. [loj3301]魔法商店

    令$A=\{a_{1},a_{2},...,a_{s}\}$,若$k\not\in A$,那么恰存在一个$A'\subseteq A$使得$c_{k}=\bigoplus_{x\in A'}c_{x} ...

  8. [atAGC050B]Three Coins

    记$p_{i}$表示该位置是否有硬币 称使得$p_{i,i+1,i+2}$都变为1的操为对$i$的添加操作,使得$p_{i,i+1,i+2}$都变为0的操作为对$i$的删除操作 考虑一个简单的操作:若 ...

  9. Winform开发的快速、健壮、解耦的几点建议

    在Winform开发领域开发过十多年的项目中,见证着形形色色的架构和官方技术的应用,从最早类似Winform模式的WebForm技术,到接着的JQuery+界面组件,再到Asp.net Core的技术 ...

  10. Java LinkedList小记

    1. 基本用法 LinkedList实现了List.Deque.Queue接口,可以按照队列.栈和双端队列的方式进行操作.LinkedList有两个构造方法,一个是默认构造,另一个接受Collecti ...