Spring——AOP学习(静态代理和动态代理模式)

Spring——AOP学习(静态代理和动态代理模式)

一、代理模式

我们知道学习Spring最重要的两个知识点就是IOC和AOP,AOP的主要思想就是动态代理模式。在了解AOP之前我们必须学习动态代理模式。
代理模式又分为静态代理和动态代理。

二、静态代理

在学习多线程的时候我们已经学了了静态代理,我们这里回顾一下。什么是静态代理?
拿出之前学习静态代理的例子:
加入你要结婚,是不是需要找个婚庆公司来帮你结婚,但是实际上结婚的还是你自己,婚庆公司也就是哪个代理对象,它可以帮你做婚前的准备等等工作,你只需要专注于结婚这件事就行了。这就是静态代理模式。代理角色需要和真实的角色实现一个共同的结婚接口。我们来回忆一下代码是怎么简单实现静态代理的:

/**
 * 静态代理模式:
 *              1.真实角色
 *              2.代理角色
 *              3.共同要实现的接口
 *     注意:
 *          代理对象代理真实角色去结婚,真实结婚的还是真实对象。
 *     优点:
 *          代理对象可以做很多真实对象做不了的事情,真实对象专心的去做自己的事情
 */
public class StaticProxy {
    public static void main(String[] args) {
        //结婚,让代理帮你,至于要将你作为对象交给代理对象,它就可以帮你完成结婚

        //获取真实角色
        You you = new You();
        //获取代理角色,并将真实角色传给代理角色
        WeddingCompany weddingCompany = new WeddingCompany(you);

        //代理觉得帮你去结婚,实际上还是你自己去结婚的,不过结婚所附带的是就不用你去做了,你只需要专注结婚,其他的事情代理帮你做好
        weddingCompany.happyMarry();
    }
}

//你
class You implements Marry{

    @Override
    public void happyMarry() {
        System.out.println("你要结婚了");
    }
}
//你的代理对象:婚庆公司
class WeddingCompany implements Marry{
	//婚庆公司需要你这个人,所以将you对象组合进来
    private You you;

    public WeddingCompany(You you) {
        this.you = you;
    }

    @Override
    public void happyMarry() {
        //结婚之前代理帮真实角色做的事
        System.out.println("结婚之前,布置现场");
        //真实角色只用专注于结婚就行了
        you.happyMarry();
        //结婚之后代理帮真实角色做的事
        System.out.println("结婚之后,惨不忍睹");
    }
}

//你们都要做的事(接口):结婚
interface Marry{
    void happyMarry();
}

这就是简单的实现了静态代理模式,在我们多线程的第二种创建方式(实现Runnable接口)中就体现了静态代理模式的思想。
那么静态代理有什么好处呢?

  • 使用静态代理模式可以让真实角色认认真真的完成自己的工作,更加纯粹,不去关注一些公共的事情
  • 公共业务需要由代理对象来实现,实现了业务的分工,体现了解耦的思想
  • 公共业务需要扩展的话非常的方便

那么静态代理又有哪些缺点?

  • 如果真实角色有很多,那么代理角色的工作量就相当的大了,开发效率就会变得很低

那么动态代理就来了…

三、动态代理

动态代理和静态代理的角色都是一样的,唯一的区别就是静态代理模式的代理类(婚庆公司)是我们提前写好的,但是动态代理的代理类是动态生成的。

动态代理分为两大类:

  • 基于JDK原生态的接口实现
  • 基于类实现
    如:CGLIB、Javassist、ASM等

其中用的比较多的是Javassist来生成动态代理。

那么我们了解动态代理之前需要掌握两个类:

  • InvocationHandler:
    InbocationHandler类是由代理实例调用处理程序实现的接口。
    invoke(Object proxy,方法 method,Object[] args)方法处理代理实例上的方法调用并返回结果。
  • Proxy:
    Proxy提供了创建动态代理类和实力的静态发方法,他也是由这些方法创建的所有动态代理类的超类。
    newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)方法返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

代码实现动态代理:

一个共同的接口:结婚

package com.muhan.proxy;

//共同的接口:结婚
public interface Marry {
    //结婚
    void happyMarry();
}

真实角色:you

package com.muhan.proxy;

//真实角色:你,实现共同结婚接口
public class You implements Marry{
    //结婚
    public void happyMarry() {
        System.out.println("你结婚了");
    }
}

代理角色(动态生成)

package com.muhan.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//动态代理类生成的接口对象
public class WeddingCompany implements InvocationHandler {
    //维护一个真实角色的引用
    private Object realObject;
    public void setYou(Object realObject) {
        this.realObject = realObject;
    }

    //动态生成代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                realObject.getClass().getInterfaces(),this);
    }


    //proxy:代理类;method:代理类的调用处理程序方法的对象
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        beforeOfMarry();
        Object result = method.invoke(realObject, args);
        afterOfMarry();
        return result;
    }

    //结婚前婚庆公司帮你做的事
    private void beforeOfMarry() {
        System.out.println("布置婚礼现场");
    }
    //结婚后婚庆公司帮你做的事
    private void afterOfMarry() {
        System.out.println("制作录像剪辑视频");
    }
}

测试类:

package com.muhan.proxy;

public class ProxyTest {
    public static void main(String[] args) {
        //创建一个真实角色
        You you = new You();
        //创建一个动态代理角色
        WeddingCompany weddingCompany = new WeddingCompany();
        //将真实角色交给代理角色
        weddingCompany.setYou(you);
        //代理角色代理真实角色结婚
        Marry proxy = (Marry) weddingCompany.getProxy();
        proxy.happyMarry();
    }
}

结果:
在这里插入图片描述

动态代理的好处:

  • 可以使真实角色专注于做自己的事情,不用去关注一些公共的事情
  • 公共的业务由代理来完成,实现业务的分工
  • 公共业务需要扩展的话,可以更加集中和方便
  • 一个动态代理一般代理一类业务,一个动态理;也可以代理多个类、接口
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值