Spring AOP前置知识 代理模式

前置知识:代理模式 它就是Spring AOP的底层实现

使用动机

结构

静态代理

角色分析

抽象角色:一般会使用接口或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色 代理真实角色后,一般会做附属的操作。
客户:访问代理对象的人

假设有上图关系,房东只是想做租房操作不想管其他的事情,于是就交给代理类来实现。 而客户想租房找的就是代理类
代码例子:
定义租房接口 房东和中介需要实现该接口

package Demo1;

public interface Rent {
    public void rent();
}

定义房东类

package Demo1;

public class Host implements Rent {
    public void rent() {
        System.out.println("房东租房!");
    }
}

定义代理类

package Demo1;

public class Proxy  implements Rent{
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    public void rent() {
        //在代理时 代理类可以做一些附属的操作
        do1();
        do2();
        do3();
        host.rent();
    }

    private void do1(){
        System.out.println("看房---");
    }
    private void do2(){
        System.out.println("签合同---");
    }
    private void do3(){
        System.out.println("收钱");
    }
}

功能实现了!

package Demo1;

public class Clinet {
    public static void main(String[] args) {
        Host host=new Host();
        Proxy proxy=new Proxy(host);
        proxy.rent();
    }
}

动态代理

上面的代码有一个致命的缺点,每一个被代理类的创建都要创建一个对应的代理类。 需要我们使用动态代理

需要了解两个类: proxy和invocationhandler




java中提供了一个动态代理类 Proxy,Proxy并不是我们上述所说的代理对象的类,而是提供了一个创建代理对象的静态方法
(newProxyInstance方法)来获取代理对象。

定义接口

package jdkproxy;

public interface SellTickets {
    public void sell();
}

定义真实类

package jdkproxy;

public class TrainStation implements SellTickets {
    public void sell() {
        System.out.println("火车票");
    }
}

定义代理类

package jdkproxy;

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

//代理工厂,用来创建代理对象
public class ProxyFactory implements InvocationHandler {
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    public Object getProxyObject(){
        /*
        * ClassLoader loader, 类加载器,由于加载代理类。可以通过目标对象获得类加载器
          Class<?>[] interfaces, 代理类实现的接口字节码对象
          InvocationHandler h 代理对象调用的处理程序
        */
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(target, args);
        return result;
    }
}

主程序

package jdkproxy;

public class Client {
    public static void main(String[] args) {
        TrainStation station=new TrainStation();
        ProxyFactory proxyFactory=new ProxyFactory();
        proxyFactory.setTarget(station);
        SellTickets proxyObject = (SellTickets) proxyFactory.getProxyObject();
        proxyObject.sell();
    }
}

posted @ 2021-03-29 10:57  一个经常掉线的人  阅读(206)  评论(0)    收藏  举报