OOP :
Object Oriented Programming
面向对象编程:代码重用——继承
AOP:
Aspect Oriented Programming
面向切面编程:代码重用——切面
在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发
然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP
在软件业,面向切面编程,是指通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内
AOP的特点:
看下图,取款和显示余额转账前都需要做身份效验,在这里其实取款和显示余额转账就是核心业务功能,而验证用户就是周边功能,这些功能在整个功能流程中是纵向重复的,所以在开始写核心业务工程的时候就可以先不要考虑,核心业务功能完成后,将身份效验等这种周边工程一次"插入"代码, 相当于把重复的代码从核心业务代码中抽取出来,这就是横向提取
参考CSDN文章进行理解:https://blog.csdn.net/guanripeng/article/details/79922787
举例二:
aop底层将采用代理机制进行实现。
接口 + 实现类 :spring采用 jdk 的动态代理Proxy。
怎么做的?基于接口去实现。回顾。
缺点:如果目标类没有实现任何接口呢?jkd动态代理就无能为力。
cglib可以对任意类生成代理对象,它的原理是对目标对象进行继承代理,如果目标对象被final修饰,那么该类无法被cglib代理。
SpringAOP的本质就是动态代理,那么Spring到底使用的是JDK代理,还是cglib代理呢?
答:混合使用。如果被代理对象实现了接口,就优先使用JDK代理,如果没有实现接口,就用用cglib代理。
三种方式:
除了aop的依赖,还要导入Spring的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
UserService和CustomAdvice
3个组件
UserService的实例
Advice通知的实例(实现MethodInterceptor的接口,通过invoke方法通知在什么之间做什么事情)
UserServiceProxy代理对象的实例(通过目标对象和interceptorName→容器中通知)
不足之处
基于java语言的AOP框架
Spring2.0之后支持了基于AspectJ的切入点表达式的支持
AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
允许直接在POJO里面定义切面类
主要用途,不改动现有代码的前提下,自定义开发。植入代码
举例
<aop:pointcut id="mypoiutcut" expression="execution(public int com.cskaoyan.sercvice.UserServiceImpl.login(String,String ))">
导入Spring-context(5+1) 和Aspectj的织入包(1),织入包使用org版本的
<dependency>
<!--织入包-->
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
注册UserService的实例
注册通知类,需要实现 MethodInterceptor 接口
在application.xml中配置
测试:
直接获取service实例,执行方法
aspect:切面
切面类=切入点+通知
作为通知方法的形参,可以通过joinPoint拿到代理对象,目标对象,方法,参数
Before:在委托类(目标类)方法执行前执行,参数类型的校验。 前置通知。
After:在委托类(目标类)方法执行之后,不管发生什么,都会执行到,类似于finally,
环绕 目标类的执行方法,通知 在切入点之前和之后都会执行。常用于增加事务
方法返回值是Object 参数是ProceedingJoinPoint,ProceedingJoinPoint对象是JoinPoint的子接口该对象只用在@Around的切面方法中
joinPoint的proceed方法类似于动态代理中的method.invoke方法
After-throwing:传入参数Throwable 和aop通知标签的throwing属性对应
抛出异常的时候执行通知。正常情况下走不到。只有发生异常的情况下才会去通知。记录一些日志。
After-returning在切入点之后执行后置通知,可以对结果进行检查。增加log
在application.xml配置文件中添加标签q
<aop:aspectj-autoproxy/>
其他通知:
切入点表达式:
容器中组件的方法上增加注解:
原文:https://www.cnblogs.com/zhaoyuan72/p/14452442.html