003 AOP介绍

什么是AOP

  • 在软件业中,AOP为Aspect Oriented Programming的缩写,意为面向切面编程
  • 作用:在不修改目标类代码的前提下,可以通过AOP技术去增强目标类的功能。通过[预编译方式]和[运行期动态代理]实现程序功能的统一维护的一种技术
  • AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
  • AOP最早由AOP联盟的组织提出的,制定了一套规范 Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
  • 利用AOP可以对业务代码中[业务逻辑]和[系统逻辑]进行隔离,从而使得[业务逻辑]和[系统逻辑]之间的耦合度降低,提高程序的可重用性,同时提高了开发效率

为什么用AOP

作用:
AOP采取横向抽取机制,补充了传统纵向继承体系(OOP)无法解决的重复性代码优化(性能监视、事务管理、安全检查、缓存),将业务逻辑和系统处理的代码(关闭连接、事务管理、操作日志记录)解耦
优势:
重复性代码被抽取出来之后,维护更加方便

  • 纵向继承体系:
    纵向继承体系

  • 横向抽取机制
    横向抽取机制

AOP相关术语介绍

  • Joinpoint(连接点)

所谓连接点指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点

  • Pointcut(切入点)

所谓切入点是指我们要对哪些Joinpoint进行拦截的定义

  • Advice(通知/增强)

所谓通知是指拦截到Joinpoint之后所要做的事情就是通知。通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

  • Introduction(引介)

引介是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field

  • Target(目标对象)

代理的目标对象

  • Weaving(织入)

是指把增强应用到目标对象来创建新的代理对象的过程

  • Proxy(代理)

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

  • Aspect(切面)

是切入点和通知的结合,以后自己编写和配置的

  • Advisor(通知器、顾问)

和Aspect相似

AOP实现之AspectJ(了解)

  • AspectJ是一个Java实现的AOP框架,它能够对java代码进行AOP编译(一般在编译期进行),让java代码具有AspectJ的AOP功能(当然需要特殊的编译器)
  • 可以这样说AspectJ是目前实现AOP框架中最成熟,功能最丰富的语言。更幸运的是,AspectJ与java程序完全兼容,几乎是无缝关联,因此对于有java编程基础的工程师,上手和使用都非常容易
  • 了解AspectJ应用到java代码的过程(这个过程称为织入),对于织入这个概念,可以简单理解为aspect(切面)应用到目标函数(类)的过程
  • 对于织入这个过程,一般分为动态织入和静态织入,动态织入的方式是在运行时动态将要增强的代码织入到目标类中,这样往往是通过动态代理技术完成的,如Java JDK的动态代理(Proxy,底层通过反射实现)或者CGLIB的动态代理(底层通过继承实现),Spring AOP采用的就是基于运行时增强的代理技术
  • AspectJ采用的就是静态织入的方式。AspectJ主要采用的是编译期织入,在这个期间使用AspectJ的acj编译器(类似javac)把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类
    在这里插入图片描述

AOP实现之Spring AOP(了解)

实现原理分析

  • Spring AOP是通过动态代理技术实现的
  • 而动态代理是基于反射设计的
  • 动态代理技术的实现方式有两种:基于接口的JDK动态代理和基于继承的CGLib动态代理
    实现原理

JDK动态代理

目标对象必须实现接口

//1.使用Proxy类来生成代理对象的一些代码如下:
/**
*	使用JDK的方式生成代理对象
*/
public class MyProxyUtils {
	public static UserService getProxy(final UserService service) {
		//使用Proxy类生成代理对象
		UserService proxy = (UserService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
		service.getClass().getInterfaces(),
		new InvocationHandler(){
			//代理对象方法一执行,invoke方法就会执行一次
			public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
				if("save".equals(method.getName())){
					System.out.println("记录日志....");
					//开启事务
				}
				//提交事务
				//让service类的save或update方法正常的执行下去
				return method.invoke(service,args);

			}
		});
		//返回代理对象
		return proxy;
	}
}


Cglib动态代理

  • 目标对象不需要实现接口
  • 底层是通过继承目标对象产生代理子对象(代理子对象中继承了目标对象的方法,并可以对该方法进行增强)
public static UserService getProxy(){
	//创建CGLIB核心的类
	Enhancer enhancer = new Enhancer();
	//设置父类
	enhancer.setSuperclass(UserServiceImpl.class);
	//设置回调函数
	enhancer.setCallback(
		new MethodInterceptor() {
			@Override
			public Object intercept(Object obj,Method method,Object[] args,MethodProxy methodProxy) throws Throwable {
				if("save".equals(method.getName())){
					//记录日志
					System.out.println("记录日志了...");
				}
				return methodProxy.invokeSuper(obj,args);
			}
		});
		//生成代理对象
		UserService proxy = (UserService) enhancer.create();
		return proxy;
}

使用

  • 其使用ProxyFactoryBean创建
  • 使用<aop:advisor>定义通知器的方式实现AOP则需要通知类实现Advice接口
  • 增强(通知)的类型有:

前置通知:org.springframework.aop.MethodBeforeAdvice
后置通知:org.springframework.aop.AfterReturningAdvice
环绕通知:org.aopalliance.intercept.MethodInterceptor
异常通知:org.springframework.aop.ThrowsAdvice

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 洁 冬冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值