Spring的AOP

aop概述

Aspect Oriented Programing 面向切面(方面)编程,

aop:扩展功能不修改源代码实现

aop采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

aop原理

  1. 横向抽取机制

    扩展功能:

    添加数据之后,添加日志功能,添加之后,记录在什么时间添加哪个用户

    传统方式:

    public class User{
    //添加新用户的方法
    public void add(){
    //添加逻辑
    //传统方式:在此修改源代码,添加日志逻辑
    }
    }

    ------》解决方案:纵向抽取机制

    缺陷:父类方法名字发生变化,在子类调用的方法也需要变化

    public class BaseUser{
    //创建添加日志的方法
    public void weitelog(){
    //添加日志逻辑 }
    }
    public class User extends BaseUser{
    //添加新用户的方法
    public void add(){
    //添加逻辑
    //功能扩展,添加日志的功能
    //调用父类方法实现日志功能
    super.writelog();
    }
    }

    ——》横向抽取机制

    aop:横向抽取机制

    底层使用 动态代理方式实现

    第一种情况

    ​ 使用动态代理方式,创建接口实现类代理对象

    ​ 创建一个和DaoImpl平级对象

    ​ 这个对象不是真的对象,代理对象

    ​ 实现DaoImpl相同的功能

    public interface Dao{
    public void add();
    }
    public class DaoImpl implements Dao{
    public void add(){
    //添加逻辑
    }
    }

    第二种情况 没有接口的情况

    使用cglib代理,没有借口情况

    public class User{
    public void add(){ }
    }
    /*动态代理实现
    *创建Uesr类的子类的对象
    *在子类里面调用父类方法完成增强
    */

aop操作相关术语

pointcut(切入点)

在类里面可以有很多方法被增强,比如实际操作中,只是增强了类里面add的方法和update方法,实际增强的方法被称为切入点

Advice(增强)

实际增强的逻辑,称为增强,比如扩展日志功能,这个日志功能称为增强

增强(通知)有以下的分类

名称 介绍
前置通知 在方法之前执行
后置通知 在方法之后执行
异常通知 方法出现异常后执行
最终通知 在后置之后执行
环绕通知 在方法之前和之后执行

Aspect(切面)

在增强应用到具体的方法上面,过程称为切面,

切面是切入点和通知(引介)的结合

以下不常用,了解即可

Joinpoint:连接点:类里面那些方法可以被增强,这些方法被称为连接点

Introduction(引介):在不修改类代码的前提上,动态添加属性和方法

Target(目标对象):要增强的类

Weaving(织入):把增强应用到目标的过程

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

public class User{
public void add(){}
public void update(){}
public void delete(){
}
public void findAll(){}
}

基于aspectj的AOP

基于aspectj的xml准备工作

@AspectJ简介

在Spring里面进行aop操作,使用aspectj实现
  1. AspectJ不是Spring的一部分,和是Spring一起使用进行AOP操作
  2. Spring2.0以后增加了对AspectJ的支持
  3. 新版本Spring建议使用AspectJ进行AOP操作
使用AspectJ实现AOP有两种方式
  1. 基于AspectJ的xml配置
  2. 基于AspectJ的注解方式

AOP操作的准备

  • 需要导入aop相关的jar包:aspects aop。

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.8.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.1.8.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>LATEST</version>
    </dependency>
    <dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
    </dependency>
  • 创建spring核心配置文件,引入aop的相关约束:the aop schema

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> </beans>

使用表达式配置切入点

  1. 切入点:实际增强的方法

  2. 常用的表达式

    execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>) 作用对象
    execution(* aop.Book.add(…)) 某个方法
    execution(* aop.Book.*(…)) 某个类的所有方法
    execution(* *.*.*(..)) 所有
    execution(* save*(…)) 匹配所以save开头的方法

    前后置通知基本相同

    <bean id="book" class="aop.Book"></bean>
    <bean id="mybook" class="aop.MyBokk"></bean>
    <!-- 配置aop操作-->
    <aop:config>
    <!-- 配置切入点-->
    <aop:pointcut id="pointcut1" expression="execution(* aop.Book.add(..))"/>
    <aop:aspect ref="mybook">
    <!-- 配置增强的类型
    method:增强类里面使用哪个方法作为前置
    pointcut-ref:作用于哪一个切入点
    -->
    <aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
    </aop:aspect>
    </aop:config>

    环绕通知

    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    //方法之前
    System.out.println("方法之前。。。。。。。");
    //抛出异常
    proceedingJoinPoint.proceed();
    //方法之后
    System.out.println("方法之后........");
    }
     <aop:around method="around" pointcut-ref="pointcut1"></aop:around>

    基于Aspect实现AOP(注解)

首先在配置文件中开启aop自动代理

<aop:aspectj-autoproxy/>

然后在增强类中编写注解

@Aspect
public class MyBook {
@Before(value = "execution(* aop.Book.*(..))")
public void before1(){
System.out.println("前置增强.......");
}
/**
*
* @param proceedingJoinPoint 用此调用被环绕的对象
*/
@Around(value = "execution(* aop.Book.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//方法之前
System.out.println("方法之前。。。。。。。");
//抛出异常
proceedingJoinPoint.proceed();
//方法之后
System.out.println("方法之后........");
}
}

@AspectJ提供不同的通知类型

  • @Before前置通知,相当于BeforeAdvice
  • @AfterReturning后置通知,相当于AfterReturningAdvice
  • @Around 环绕通知,相当于MethodIntercepetor
  • @AfterThrowing抛出通知,相当于ThrowAdvice
  • @After 最终final通知,不管是否异常,该通知都会执行

SpringAOP入门的更多相关文章

  1. Spring-Aop入门

    (一)Aop术语定义 1.通知(advice) 通知定义了切面要做什么工作,即调用的方法,同时定义了什么时候做这些工作,即以下五种类型 (1)前置通知(Before) :在目标方法调用之前执行切面方法 ...

  2. 一篇文章带你掌握主流基础框架——Spring

    一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...

  3. 带你入门代理模式/SpringAop的运行机制

    SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...

  4. SpringAOP简单入门

    注解形式 步骤一.定义一个interface public interface ArithmeticCalculator { double plus(int i, int j); double sub ...

  5. Spring MVC入门

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

  6. SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)

    SpringMVC简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 Spring结构图 Spr ...

  7. SpringMvc核心流程以及入门案例的搭建

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

  8. SpringMVC之入门

    Spring MVC简介 Spring MVC:Spring MVC也叫Spring Web MVC,属于表现层框架,是Spring中的一份子. Spring MVC执行流程图 第一个SpringMV ...

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

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

随机推荐

  1. JavaScript对象(一)

    Part One:对象的创建对象的创建,可以使用new Object() 或者 Object.creat(),该方法为静态函数 var foo = Object.create({x:1,y:2});  ...

  2. 06 Linux 的常用命令

    Linux 刚面世时并没有图形界面,所有的操作全靠命令完成,如 磁盘操作.文件存取.目录操作.进程管理.文件权限 设定等 在职场中,大量的 服务器维护工作 都是在 远程 通过 SSH 客户端 来完成的 ...

  3. 关于.NET中的控制反转及AutoFac的简单说明

    目录 1.控制反转 1.1 什么是依赖? 1.2 什么是控制反转? 1.3 什么是依赖注入? 1.4 简单总结 2.控制反转容器 2.1 IOC容器说明 2.2 使用AutoFac的简介示例 3 使用 ...

  4. Visual Studio 安装中出现闪退

    问题描述:win7 系统下, 安装 Visual Studio Community 2017 过程中,安装界面闪退 原因:Visual Studio 的版本低了 解决方案:选择 Visual Stud ...

  5. mimtproxy的使用(windows)

    1.安装 pip3 install mitmproxy 或者下载安装指定版本:https://mitmproxy.org/downloads/ 2.配置证书 对于mitmproxy来说,如果想要截获H ...

  6. 《前端之路》- TypeScript(二) 函数篇

    目录 一.定义函数方法 二.定义函数传参 三.可选传参 四.默认传参 五.传递剩余参数 六.函数重载 七.箭头函数 八.总结 一.定义函数方法 在 es5 中定时函数的方法有 命名函数和函数表达式(匿 ...

  7. javaScript 基础知识汇总 (十三)

    1.Class 在JavaScript中 calss即类是一种函数 基本语法 class Myclass{ constructor(){} method1(){} method2(){} method ...

  8. 【Weiss】【第03章】练习3.18:检查平衡符号

    [练习3.18]用下列语言编写检测平衡符号的程序 a.Pascal ( begin/end, ( ), [ ], { } ). b.C语言( /* */, ( ), [ ], { }). c.解释如何 ...

  9. MySQL笔记(4)-- 索引优化

    索引失效情况: 最佳左前缀法则:如果索引了多列,要遵循最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列:[覆盖索引有a,b,c,条件中使用了b或bc都导致该索引失效:如果条件使用了ac ...

  10. 批量redis未授权检测工具&批量redis弱口令爆破工具

    今天需要然后就百度搜索了一波,然后自己稍微改了一下: #!/usr/bin/python3 # -*- coding: utf-8 -*- """ @Author: 偷来 ...