Spring Aop实现方式及原理(CGLIB依赖)

一,Aop是什么

Aop是Spring框架的第二大核心(第一是ioc)。

Aop是一个面向切面编程。那什么是面相切片编程呢,也就是一类特定问题,就比如拦截器什么的就是一个切面,当然拦截器也是Aop思想的一种实现。简单说Aop也就是对某一类事情的集中处理。

1.1Aop的优势

1,不用修改源代码就可以进行功能增强或者改变。

2,减少了重复代码

3,提高开发效率

4,维护方便

二,Aop核心概念

切面:定义了横切关注点的行为和通知,也就是告诉程序哪里需要增强。(切点+通知)

切点:指定切面的应用范围,定义了那些连接点会被该切面所影响。

连接点:程序执行过程中的某个特定点,如方法调用和异常抛出。

通知:具体要做那些工作,也就是把共性功能体现为一个方法。

2.1通知类型

Spring中的Aop通知类型有以下几种:此类标注的通知方法在目标方法前后都被执行

• @Around:环绕通知,此类标注的通知方法在目标方法前后都被执行

• @Before:前置通知,此类标注的通知方法在目标方法前都被执行

• @After:后置通知,此类标注的通知方法在目标方法后都被执行,无论是否有异常都会执行

• @AfterReturning:返回后通知,此类标注的通知方法在目标方法前后都被执行,有异常不会执行

• @AfterThrowing:异常后通知,此注解标注的通知方法发生异常后执行

三,Aop原理

3.1代理模式

代理模式也就是提供了一个代理类,让我们在调用目标方法的时候,不在对目标方法直接调用,而是通过代理来间接调用。就比如艺人的经纪人一样的。

也主要分为两种:

静态代理:由程序员创建代理类或特定⼯具⾃动⽣成源代码再对其编译,在程序运⾏前代理类的 .class⽂件就已经存在了。

动态代理:在程序运行的时候,运用反射机制创建而成。

 3.1.1静态代理

也就好比你去租房子这个房子的中介早就分好了一样。

流程也就是定义接口,好比定义中介要做的事情,

实现接口,也就是房东出租房子,

代理,中介帮忙买房子,

使用,也就是挂到租借中心

这样一看,这都是定的,如果想修改就很不方便,所以日常开发也见不到这种。

3.1.2动态代理

动态这时我们就不需要对每个目标创建一个单独的代理,而是推迟到程序运行时由jvm来实现。

房屋这边就比如你去了租房才给你分配中介,而不是这个房子必须那个中介。

动态代理这边常见的实现方式有两种:

JDK动态代理

CGLIB动态代理

这边主说CGLIB。因为JDK有一个致命问题就是只能代理实现了接口的类。

CGLIB动态实现步骤:

1. 定义⼀个类(被代理类)

 2. ⾃定义MethodInterceptor 并重写intercept ⽅法, intercept ⽤于增强⽬标⽅法,和JDK动态代理中的invoke ⽅法类似

3. 通过Enhancer类的create()创建代理类

要注意的是这边使用CGLIB要添加依赖:

<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>3.3.0</version>
</dependency>

代码实现:⾃定义MethodInterceptor:方法拦截器

public class CGLIBInterceptor implements MethodInterceptor {
 //⽬标对象, 即被代理对象 
     private Object target;
     public CGLIBInterceptor(Object target){
         this.target = target;
 }
     @Override
 public Object intercept(Object o, Method method, Object[] objects, 
MethodProxy methodProxy) throws Throwable {
 // 代理增强内容 
     System.out.println("我是中介, 开始代理");
 //通过反射调⽤被代理类的⽅法 
     Object retVal = methodProxy.invoke(target, objects);
 //代理增强内容 
     System.out.println("我是中介, 代理结束");
     return retVal;
 }
}

创建代理类:

public class DynamicMain {
 public static void main(String[] args) {
     HouseSubject target= new RealHouseSubject();
     HouseSubject proxy= (HouseSubject) 
Enhancer.create(target.getClass(),new CGLIBInterceptor(target));
     proxy.rentHouse();
 }
}

解释一下这两个:

MethodInterceptor用于增强目标方法。

Enhancer.create()⽤来⽣成⼀个代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值