SpringAOP入门
Spring的AOP
aop概述
Aspect Oriented Programing 面向切面(方面)编程,
aop:扩展功能不修改源代码实现
aop采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
aop原理
横向抽取机制
扩展功能:
添加数据之后,添加日志功能,添加之后,记录在什么时间添加哪个用户
传统方式:
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实现
- AspectJ不是Spring的一部分,和是Spring一起使用进行AOP操作
- Spring2.0以后增加了对AspectJ的支持
- 新版本Spring建议使用AspectJ进行AOP操作
使用AspectJ实现AOP有两种方式
- 基于AspectJ的xml配置
- 基于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>
使用表达式配置切入点
切入点:实际增强的方法
常用的表达式
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入门的更多相关文章
- Spring-Aop入门
(一)Aop术语定义 1.通知(advice) 通知定义了切面要做什么工作,即调用的方法,同时定义了什么时候做这些工作,即以下五种类型 (1)前置通知(Before) :在目标方法调用之前执行切面方法 ...
- 一篇文章带你掌握主流基础框架——Spring
一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...
- 带你入门代理模式/SpringAop的运行机制
SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...
- SpringAOP简单入门
注解形式 步骤一.定义一个interface public interface ArithmeticCalculator { double plus(int i, int j); double sub ...
- Spring MVC入门
1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...
- SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)
SpringMVC简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 Spring结构图 Spr ...
- SpringMvc核心流程以及入门案例的搭建
1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...
- SpringMVC之入门
Spring MVC简介 Spring MVC:Spring MVC也叫Spring Web MVC,属于表现层框架,是Spring中的一份子. Spring MVC执行流程图 第一个SpringMV ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
随机推荐
- seo搜索优化教程14-seo搜索优化实战
为了使大家更方便的了解及学习网络营销推广.seo搜索优化,星辉信息科技强势推出seo搜索优化教程.此为seo教程第14课 根据前面学习的seo搜索优化内容,星辉科技进行总结性的分析,形成一份标准的se ...
- 免ROOT卸载手机自带软件详细教程
一.准备条件 1.电脑一台 2.手机一部 3.WiFi 二.下载所需资源 微信扫码进入搜索,选择安卓软件卸载工具 根据图中提示,按照自己的系统进行下载 三.下载完后解压(以Windows为例),解压后 ...
- c++作业22题
一.单选题(共22题,100.0分) 1 已知int i=5,下列do-while循环语句的循环次数是 do{ cout<<i - -<<endl; i - -; }while ...
- 爬虫过程中获取不到列表页的url
例1: 采集某网站的时候根据网页页面显示的url链接提取的, 最后始终没有数据返回. 主要原因是页面源码中标签的 href 属性值和页面上的不一样. 页面上显示是‘http://www.xxx.org ...
- redis的批量操作命令pipeline(PHP实现)
redis执行一条命令有四个过程:发送命令.命令排队.命令执行.返回结果:整个过程是一个往返时间(RTT).如果有n条命令,就会消耗n次RTT.Redis的客户端和服务端可能部署在不同的机器上.在两地 ...
- go bufio 、os 包
程序使用短变量声明创建bufio.Scanner类型的变量input. input := bufio.NewScanner(os.Stdin) 该变量从程序的标准输入中读取内容.每次调用input.S ...
- ClassLoader&双亲委派&类初始化过程
1.class sycle 类加载的生命周期:加载(Loading)–>验证(Verification)–>准备(Preparation)–>解析(Resolution)–>初 ...
- js 实现简单的选项卡
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 菜鸟对java和Go的理解
1.go对比java go通过结构体嵌套+接口实现类似面向对象中的继承和多态.个人认为尤其是go的接口抓住了多态的本质.而Go提倡的面向接口的思想也可能使得架构上更加解耦. 2.关于Go不要通过共享内 ...
- 建议11:增强数组排序的sort功能
sort方法不仅按字母顺序进行排序,还可以根据其他顺序执行操作.这时就必须为方法提供一个比较函数的参数,该函数要比较两个值,然后返回一个用于说明这两个值得相对顺序的数字.比较函数应该具有两个参数a和b ...