AOP和动态代理

前言


都说面向切面编程是代理模式的延续,今天就来研究一下这两者之间的关系

代理模式:一个类代表另一个类的功能。

静态代理的DEMO


话不多说,先看个关于静态代理的例子:有一个shape的接口,rectangle和simpleproxy,都实现shape的接口,这个接口中有draw和erase两个方法,simpleproxy保存一个rectangle的引用,代替实体去实现“画”和“清除”的方法

接口:shape

package simpleproxy;

public interface Shape {
    void draw();
    void erase();
}


Rectangle

package simpleproxy;

public  class Rectangle implements Shape{
    @Override
    public void draw(){
        System.out.println("draw Rectangle");
    }

    @Override
    public void erase(){

        System.out.println("erase Rectangle");
    }
}


SimpleProxy

package simpleproxy;

public class SimpleProxy implements Shape {
    Shape shape;

    void setShape(Shape shape){
        this.shape=shape;
    }

    @Override
    public void draw(){
        System.out.println("create Rectangle");
        shape.draw();
    }

    @Override
    public void erase(){
        shape.erase();
        System.out.println("destroy Rectangle");
    }
}


SimpleProxyDemo控制台

package simpleproxy;

public class SimpleProxyDemo {
    private Shape shape;

    public SimpleProxyDemo(Shape shape){
        this.shape=shape;
    }

    public static void main(String[] args ){
        Rectangle target=new Rectangle();

        SimpleProxy proxy=new SimpleProxy();
        proxy.setShape(target);
        SimpleProxyDemo demo=new SimpleProxyDemo(proxy);
        demo.shape.draw();
        demo.shape.erase();

    }
}

这里写图片描述

UML

这里写图片描述

但是我们仔细研究一下静态代理的代码,只有这个与之相对应的代理类可以代替rectangle类去做一些事情,没有办法让别的代理去做,只能“一对一”,所以说代码灵活性不够,但是我们如何解决这个问题呢??那就是动态代理,Spring AOP使用动态代理技术有两只机制:一个是JDK实现;另一种是cglib实现,下边讨论一下JDK的方式

动态代理(jdk)DEMO


接口Shape和类Rectangle

同上


Handler

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

//把代理的逻辑放在InvocationHandler实现类中,从而可以让任意接口代理相同的逻辑
//InvocationHandler:代理实例的调用处理程序实现的接口
public class Handler implements InvocationHandler{

    Object target;

    Handler(Object target){
        this.target=target;
    }


    @Override
    public Object invoke(Object proxy,Method method,Object[] args)throws Throwable
    {
        System.out.println("create Target");

        //当代理对象调用真实对象的方法时,他会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        //通过反射执行某个类的某方法
        Object o=method.invoke(target, args);

        System.out.println("destroy Target");
        return o;
    }
}
<br>

客户端

package simpleproxy;
import java.lang.reflect.Proxy;

public class DynamicProxyDemo {
    public static void main(String[] args){
        //实际的类
        Rectangle rectangle=new Rectangle();    
        Handler h=new Handler(rectangle);
        //通过java API创建类newProxyInstance(动态加载代理类,代理类实现接口,使用handler)
        //返回一个的顶接口的代理类实例(动态生成代理的核心)
        Shape proxyShape=(Shape)Proxy.newProxyInstance
            (Rectangle.class.getClassLoader(), 
            Rectangle.class.getInterfaces(), h);
        proxyShape.draw();
        proxyShape.erase();
    }
}

接口Shape和Rectangle没有变化,不重复写了

JDK动态代理如何实现?

JDK动态代理主要这几java.lang.reflect包下的两个类:Proxy类和InvocationHandler接口

InvocationHandler每一个动态代理类都必须实现InvocationHandler这个接口,每一个代理类的实例都关联到一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会反射到这个接口下的invoke方法进行调用


Proxy这个类用来动态创建一个代理对象的类

这里写图片描述

总结


动态代理解决了静态代理一对一的问题,使用反射机制可以动态的决定由任意类型的代理类去代理实际的类实现接口,提高了系统的可扩展性和可维护性,下一篇将总结具体的动态代理在spring如何实现AOP编程~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值