23种设计模式-动态代理模式

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

  • 动态代理的代理类是动态生成的,不是我们直接写好的。

  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理

    • 基于接口——JDK动态代理 【我们在这里使用】

    • 基于类:cglib

    • java字节码实现:javasisit  。 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态"AOP"框架。  其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

  需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序

 

  动态代理的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务

  • 公共也就交给代理角色!实现了业务的分工!

  • 公共业务发生扩展的时候,方便集中管理!

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

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

 改造案例

租房的接口

package com.kuang.demo03;

public interface Rent {
        public void rent();

}

房东这个类

package com.kuang.demo03;

import com.kuang.demo03.Rent;

//房东是真实角色
public class Host implements Rent {

    public void rent() {
        System.out.println("房东要出租房子!");

    }
}

代理角色

package com.kuang.demo03;

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

//等会儿会用这个类 自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//    被带肋的接口
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //    生成得到的代理类
    public Object getProxy(){
   return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
    
//处理代理实体并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {     //动态代理的本质就是使用反射机制 seeHouse(); fare(); Object result= method.invoke(rent, args); return result; } public void seeHouse(){ System.out.println("中介带着看房子!"); } public void fare(){ System.out.println("中介收费!"); } }

测试类

package com.kuang.demo03;

public class Client {
    public static void main(String[] args) {
//        真实角色
        Host host = new Host();
//        代理角色:现在没有 要通过处理程序生成一个出来
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
//        通过调用程序处理角色来处理我们要调用 的接口对象
        pih.setRent(host);

        Rent proxy = (Rent) pih.getProxy(); //这里开始创建代理的对象  proxy就是动态生成的,我们并没有写
        proxy.rent();  
    }
}

进一步改造

package com.kuang.demo04;

import com.kuang.demo03.Rent;

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

//等会儿会用这个类 自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //  被代理的接口 改为target  可以是任意的接口
    private Object target;

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

    //    ProxyInvocationHandler :生成得到的代理类
    public Object getProxy(){
             return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                     target.getClass().getInterfaces(),this);
    }
    //InvocationHandler: 处理代理实体并返回结果
    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+"方法");

    }
}

测试类

package com.kuang.demo04;

import com.kuang.demo02.UserService;
import com.kuang.demo02.UserServiceImpl;

public class Client {
    public static void main(String[] args) {
//        真实角色
        UserServiceImpl userService = new UserServiceImpl();
//        代理角色 不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(userService);//设置要代理的对象
//        生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.query();
    }
}

猜你喜欢

转载自www.cnblogs.com/yppaopao/p/13171430.html