Java代理

代理模式

使用spring的Aop必须要理解什么是代理模式

分类:

  1. 静态代理

  2. 动态代理

  • 代理模式:自己要实现某个功能,只想得到功能的结果,把乱七八遭的构建啥的都交给另外的人,让他代理,比如房东出租房子,他只想出租就行了,价格, 合同啥的都交给代理处理。

静态代理

  • 抽象角色:一般会使用接口或者抽象类解决

  • 真实角色:被代理的角色

  • 代理角色:代理真实角色,代理真实角色后,我们会做一些附属操作

  • 客户:访问代理对象的人

  • 代理好处:使真实角色更加纯粹,不用管理公共事务,公共交给代理,实现业务的分工,公共事务发生扩展的时候,方便集中管理 不改变原有代码,在基础功能之上扩展

  • 缺点,一个真实角色就要产生一个代理,代码量会翻倍,开发效率低

public class Host implements Rent{    public void rent() {
        System.out.println("房东要出租房屋");
    }
}public class Proxy {    private Host host;    public Proxy(){

    }    public Proxy(Host host){        this.host = host;
       
    }    public void rent(){        this.host.rent();
        seehouse();
        fare();
    }    public void givePrice(){
    }   
}//本来要调用Host的rent。把host给proxy代理,只要用proxy就可以实现host的功能,还可以扩展功能
``````java
public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}

public class UserServieImpl implements UserService{

    public void add() {
        this.log("add");
        System.out.println("add方法");
    }

    public void delete() {
        log("delete");
        System.out.println("delete方法");
    }

    public void update() {
        log("update");
        System.out.println("update方法");
    }

    public void query() {
        log("query");
        System.out.println("query方法");
    }
    public void log(String msg){
        System.out.println("增加了"+msg+"方法");
    }
}
public class Poxy {
    UserServieImpl userServie;

    public void setUserServie(UserServieImpl userServie) {
        this.userServie = userServie;
    }
    void add(){
        userServie.add();
    }
    void update(){
        userServie.update();
    }
    void delete(){
        userServie.delete();
    }
    void query(){
        userServie.query();
    } 
}
public class Client {
    public static void main(String\[\] args) {
        Poxy poxy = new Poxy();
        UserServieImpl userServie = new UserServieImpl();
        poxy.setUserServie(userServie);
        poxy.add();
    }
}

动态代理

  • 动态代理和静态代理一样

  • 动态代理的代理类是动态生成的,不是自己编写的

  • 分为两大类:

  1. 基于接口的代理:像jdk动态代理

  2. 基于类的动态代理:cglib

  3. java字节码实现:javasist

  • 通过jdk,需要了解两个类 Proxy:代理 ,InvocationHandler:调用处理程序

  • 一个动态代理代理的是一个接口吗,一般就是对应的业务

  • 一个动态代理类可以代理多个类,只要是实现的是同一个接口即可

public interface Rent {
    public void rent();
}


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



//Proxy: 生成动态代理实例
//InvocationHandler    调用处理程序并返回结果
public class ProxyInvocationHandler implements java.lang.reflect.InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //    Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
//            new Class<?>\[\] { Foo.class },
//            handler);
    //生成代理对象,arg1:class路径 arg2:接口对象 arg3:本类调用
    public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object\[\] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(target,args);
        return result;
    }
    public void log(String msg){
        System.out.println("执行了"+msg+"方法");
    }
}

public class Client {
    public static void main(String\[\] args) {
        //真实角色
        Host host = new Host();
        //代理角色
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //通过调用程序处理角色去处理我们要调用的接口对象
        pih.setTarget(host);
        Rent rent =(Rent)pih.getProxy();
        rent.rent();
    }

}