Spring AOP(3)

目录

Spring AOP原理

代理模式

代理模式中的主要角色

静态代理

 动态代理

总结:面试题

什么是AOP?

Spring AOP实现的方式有哪些?

Spring AOP实现原理 

Spring使用的是哪种代理方式?

JDK和CGLIB动态代理的区别?


Spring AOP原理

代理模式

代理模式, 也叫委托模式.

定义: 为其他对象提供一种代理以控制对这个对象的访问. 它的作用就是通过提供一个代理类, 让我们在调用目标方法的时候, 不再是直接对目标方法进行调用, 而是通过代理类间接调用.

在某些情况下, 一个对象不适合或者不能直接引用另一个对象, 而代理对象可以在客户端和目标对象之间起到中介的作用.

使用代理前:

 

使用代理后:

比如当进行房屋租赁时, 房主会将房屋授权给中介, 由中介来代理看房, 房屋咨询等服务.

代理模式中的主要角色

1.Subject: 业务接口类. 可以是抽象类或者接口(不一定有)

2.RealSubject: 业务实现类. 具体的业务执行, 也就是被代理对象.

3.Proxy:代理类. RealSubject的代理. 

譬如房屋租赁

Subject: 就是提前定义了房东要做的事情, 交给中介代理, 也是中介要做的事情.

RealSubject: 房东

Proxy: 中介

UML类图如下:

 

代理模式可以在不修改被代理对象的基础上, 通过扩展代理类, 进行一些功能的附加和增强.

根据代理的创建时期, 代理模式分为静态代理和动态代理

静态代理: 由程序员创建代理类或特定工具自动生成源代码再对其编译, 让程序运行前代理类的 .class 文件就已经存在了.

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

静态代理

静态代理: 在程序运行前, 代理类的.class文件就已经存在了. (在出租房子之前, 中介已经做好了相关的工作, 就等租户来租房子了).

以房屋租赁为例编写代码:

1.定义接口(定义房东要做的事情, 也是中介需要做的事情).

public interface HouseSubject {
    void rentHouse();
}

2.实现接口(房东出租房子)

public class RealHouseSubject implements HouseSubject{
    @Override
    public void rentHouse() {
        System.out.println("我是房东, 我出租房⼦");
    }
}

3.代理(中介, 帮房东出租房子)

public class HouseProxy implements HouseSubject{
    //将被代理对象声明为成员变量
    private HouseSubject houseSubject;
    public HouseProxy(HouseSubject houseSubject) {
        this.houseSubject = houseSubject;
    }
    @Override
    public void rentHouse() {
        //开始代理
        System.out.println("我是中介, 开始代理");
        //代理房东出租房⼦
        houseSubject.rentHouse();
        //代理结束
        System.out.println("我是中介, 代理结束");
    }
}

4.使用:

public class StaticMain {
    public static void main(String[] args) {
        HouseSubject subject = new RealHouseSubject();
        //创建代理类
        HouseProxy proxy = new HouseProxy(subject);
        //通过代理类访问⽬标⽅法
        proxy.rentHouse();
    }
}

运行结果:

 

上面代理的实现方式就是静态代理.

从上述程序中可以看出, 虽然静态代理完成了对目标对象的代理, 但是由于代码都写死了, 对目标对象的每个方法的增强都是手动完成, 非常不灵活.

比如当增加业务时(增加房屋出售), 就还是要编写大量代码.

我们修改接口(Subject)和业务实现类(RealSubject)时, 还需要修改代理类(Proxy).

同样地, 如果有新增接口(Subject)和业务实现类(RealSubject), 也需要对每个业务实现类新增代理类(Proxy).

 动态代理

相比于静态代理来说, 动态代理更加灵活.

我们不需要针对每个目标对象都单独创建一个代理对象, 而是把这个创建代理对象的工作推迟到程序运行时由JVM实现. 也就是说动态代理在程序运行时, 更具需要动态创建生成.

比如房屋中介, 我不需要提前预测都有哪些业务, 而是业务来了我再根据情况创建.

 Java也对动态代理进行了实现, 并给我们提供了一些API, 常见的实现方式有两种:

1.JDK动态代理.

2.CGLIB动态代理.

 一般代理模式开发人员基本用不着,一般是开发框架的人用的, 所以不过多介绍(看了估计也容易忘), 仅给出代码:

//JDK代理
public class JDKInvocationHandler implements InvocationHandler {
    private RealHouseSubject target;
 
    public JDKInvocationHandler(RealHouseSubject target) {
        this.target = target;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始代理");
        Object o = method.invoke(target, args);
        System.out.println("结束代理");
        return o;
    }
}
 
//main方法
        RealHouseSubject subject = new RealHouseSubject();
        Subject proxy= (Subject)Proxy.newProxyInstance(subject.getClass().getClassLoader(),
                new Class[]{Subject.class},new JDKInvocationHandler(subject));
        proxy.rentHouse();

 主要这里注意两个区别:

JDK可以代理接口, 不可以代理类.

CGLIB既可以代理接口也可以代理类.

 

注意Spring和SpringBoot在这里AOP的实现也是有差异的, 代理工厂中有一个参数proxyTargetClass. 默认Spring是false, 默认接口使用jdk代理. SpringBoot从2.x之后设置为true, 默认全部使用CGLib实现代理. 

总结:面试题

什么是AOP?

答: AOP是一种思想, 是对某一类事情的集中处理. Spring框架实现了AOP, 所以称为SpringAOP.

Spring AOP实现的方式有哪些?

1.基于注解@Aspect来实现.

2.基于自己写的@MyAspect自定义注解来实现

3.基于XML配置的方式实现.

4.基于代理实现. 

Spring AOP实现原理 

Spring AOP主要使用到了动态代理的方式: 动态代理是一种在运行时生成代理对象的机制, Spring AOP利用动态代理技术在方法调用时将切面逻辑织入目标对象中, 实现横切关注点的功能. 具体来说, Spring AOP使用JDK动态代理和CGLIB动态代理来实现对目标对象的代理, 以便在方法调用前后执行额外逻辑.

Spring使用的是哪种代理方式?

在Spring中, 代理工厂中的proxyTargetClass 默认为false. 如果实现了接口, 就是用JDK代理. 如果未实现接口只有实现类, 就是用CGLib代理.

从Spring Boot从2.x之后, proxyTargetClass默认为true, 默认使用CGLib代理

JDK和CGLIB动态代理的区别?

JDK动态代理适用于代理实现了接口的对象, 而CGLIB动态代理适用于代理没有实现接口的对象. JDK动态代理利用反射生成代理对象. 而CGLIB动态代理则是通过继承目标对象并重写方法来实现代理. 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值