您的位置:首页 > 编程语言 > Java开发

java之aop编程spring篇

2019-01-17 18:21 155 查看

AOP:
AOP思想的实现一般都是基于 代理模式 ,在JAVA中一般采用JDK动态代理模式,但是我们都知道,JDK动态代理模式只能代理接口而不能代理类。因此,Spring AOP 会这样子来进行切换,因为Spring AOP 同时支持 CGLIB、ASPECTJ、JDK动态代理。

如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;
如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类——不过这个选择过程对开发者完全透明、开发者也无需关心。

静态代理(接口类:真实实体类:代理类:实现接口)、JDK动态代理(反射获取类与方法)、CGLIB动态代理讲解(直接对实现类进行操作而非接口)
https://www.geek-share.com/detail/2693599520.html

动态代理
在讲JDK的动态代理方法之前,不妨先想想如果让你来实现一个可以任意类的任意方法的代理类,该怎么实现?有个很naive的做法,通过反射获得Class和Method,再调用该方法,并且实现一些代理的方法。我尝试了一下,很快就发现问题所在了。于是乎,还是使用JDK的动态代理接口吧。

JDK自带方法
首先介绍一下最核心的一个接口和一个方法:

java.lang.reflect包里的InvocationHandler接口:

public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
我们对于被代理的类的操作都会由该接口中的invoke方法实现,其中的参数的含义分别是:

proxy:被代理的类的实例
method:调用被代理的类的方法
args:该方法需要的参数
使用方法首先是需要实现该接口,并且我们可以在invoke方法中调用被代理类的方法并获得返回值,自然也可以在调用该方法的前后去做一些额外的事情,从而实现动态代理,下面的例子会详细写到。

一个很重要的静态方法是java.lang.reflect包中的Proxy类的newProxyInstance方法:

同一个动态代理类来进行代理,实现了“一次编写到处代理”的效果。但是这种方法有个缺点,就是被代理的类一定要是实现了某个接口的,这很大程度限制了本方法的使用场景。

一起来谈谈 Spring AOP!(spring最重要 也就是前6章)
https://juejin.im/post/5aa7818af265da23844040c6

一、什么是AOP?
要谈AOP,那么AOP到底是什么呢?AOP即面向切面编程,相比OOP–面向对象编程,由于面向对象中最基本的单位是类,实例,很自然我们会想到AOP中最基本的单位可能就是所谓的切面了,你可能会问,那切面又是个什么东西,我想说,现在不懂没关系,下面我会讲到。我们先来看一段Spring中关于AOP的定义:

面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

上面谈到,AOP可以分离系统的业务逻辑和系统服务(日志,安全等),这个功能我想是不难明白(原理是使用了代理模式),但关键是为什么要将这两种进行分离呢?或者说这样做有什么好处?
在日常的软件开发中,拿日志来说,一个系统软件的开发都是必须进行日志记录的,不然万一系统出现什么bug,你都不知道是哪里出了问题。举个小栗子,当你开发一个登陆功能,你可能需要在用户登陆前后进行权限校验并将校验信息(用户名,密码,请求登陆时间,ip地址等)记录在日志文件中,当用户登录进来之后,当他访问某个其他功能时,也需要进行合法性校验。想想看,当系统非常地庞大,系统中专门进行权限验证的代码是非常多的,而且非常地散乱,我们就想能不能将这些权限校验、日志记录等非业务逻辑功能的部分独立拆分开,并且在系统运行时需要的地方(连接点)进行动态插入运行,不需要的时候就不理,因此AOP是能够解决这种状况的思想吧!

AOP中的基本概念
不得不说,AOP的概念是真的多且难以理解,不过不用担心,聪明的你已经准备好战胜它们了。

通知(Adivce)

通知有5种类型:

Before
在方法被调用之前调用

After
在方法完成后调用通知,无论方法是否执行成功

After-returning
在方法成功执行之后调用通知

After-throwing
在方法抛出异常后调用通知

Around
通知了好、包含了被通知的方法,在被通知的方法调用之前后调用之后执行自定义的行为
我们可能会问,那通知对应系统中的代码是一个方法、对象、类、还是接口什么的呢?我想说一点,其实都不是,你可以理解通知就是对应我们日常生活中所说的通知,比如‘某某人,你2019年9月1号来学校报个到’,通知更多地体现一种告诉我们(告诉系统何)何时执行,规定一个时间,在系统运行中的某个时间点(比如抛异常啦!方法执行前啦!),并非对应代码中的方法!并非对应代码中的方法!并非对应代码中的方法!

切点(Pointcut)
哈哈,这个你可能就比较容易理解了,切点在Spring AOP中确实是对应系统中的方法。但是这个方法是定义在切面中的方法,一般和通知一起使用,一起组成了切面。

连接点(Join point)
比如:方法调用、方法执行、字段设置/获取、异常处理执行、类初始化、甚至是 for 循环中的某个点
理论上, 程序执行过程中的任何时点都可以作为作为织入点, 而所有这些执行时点都是 Joint point
但 Spring AOP 目前仅支持方法执行 (method execution)
也可以这样理解,连接点就是你准备在系统中执行切点和切入通知的地方(一般是一个方法,一个字段)

切面(Aspect)
切面是切点和通知的集合,一般单独作为一个类。通知和切点共同定义了关于切面的全部内容,它是什么时候,在何时和何处完成功能。

引入(Introduction)
引用允许我们向现有的类添加新的方法或者属性

织入(Weaving)
组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

spring AOP 通知参数的传递, 推荐阅读
https://www.geek-share.com/detail/2642418625.html
Spring核心系列之AOP(一)--------------这篇文章需要重点注意
https://juejin.im/post/5a55af9e518825734d14813f

关于 Spring AOP (AspectJ) 你该知晓的一切
https://www.geek-share.com/detail/2698635247.html

目的
1、降低模块之间的耦合度

2、使系统容易扩展

3、更好的代码复用。

spring源码剖析(五)利用AOP实现自定义Spring注解
https://www.geek-share.com/detail/2671827784.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: