java 代理模式 (静态代理,jdk动态代理,cglib动态代理)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011877584/article/details/81942137

昨晚上敲了个代理的demo(实现了下静态代理,jdk动态代理和cglib代理)。贴出来:
这里写图片描述

具体代码:
* 接口:IRunner

       package dailimoshi;

public interface IRunner {
    void run();
}

*实现类Runner

package dailimoshi;

public class Runner implements IRunner{

    @Override
    public void run() {
        System.out.println("运动员正在跑步...");
    }
}

*静态代理
静态代理 在编译时期就确定好的。
代理类和被代理类具有相同的接口。

package dailimoshi;

import java.util.Random;

public class StaticRunnerAgent implements IRunner{

    private Runner target;


    public StaticRunnerAgent(Runner target) {
        super();
        this.target = target;
    }


    @Override
    public void run() {
         Random rand = new Random();
        if(rand.nextBoolean()){
            System.out.println("运动员代理安排运动员跑步");
            target.run();
        }else{
            System.out.println("运动员代理心情不好,不安排运动员跑了..");
        }
    }   
}

*jdk动态代理

package dailimoshi;

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

/**
 * 这个是动态代理类
 * @author fjf
 * 2018年8月21日 16:15:04
 * 
 * 
 * 
 */
public class DynamicRunerAgent {

    private IRunner target;

    public DynamicRunerAgent(IRunner target) {
        super();
        this.target = target;
    }

    public IRunner getProxy(){
        IRunner proxy = null;
        //获得类加载器   目标类和代理类 都是这个类加载器
        //ClassLoader loader = target.getClass().getClassLoader();
        ClassLoader loader = IRunner.class.getClassLoader();
        //代理对象的接口  和  目标对象的接口是一样的
        Class[] interfaces = new Class[]{IRunner.class};

        //调用处理器
        InvocationHandler h = new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {

                String  result =" ";
                   Random rand = new Random();
                    if(rand.nextBoolean()){
                        System.out.println("jdk动态代理--代理人安排运动员跑步 " );
                          result = (String) method.invoke(target, args);
                    }else{
                        System.out.println("动态代理--代理人心情不好,不安排运动员。 " );
                    }
                return result;
            }
        };

        proxy = (IRunner) Proxy.newProxyInstance(loader, interfaces, h);
        return proxy;   
    }
}

*cglib动态代理

package dailimoshi;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;


/**
 * 使用cglib 来动态代理
 * @author fjf
 * 2018年8月22日 11:44:55
 */

public class CglibRunnerAgent implements MethodInterceptor {


    private Object target;    //Cglib需要代理的目标对象

     public Object createProxyObject(Object obj) {  
            this.target = obj;  
            Enhancer enhancer = new Enhancer();  
            enhancer.setSuperclass(obj.getClass());  
            enhancer.setCallback(this);  
            Object proxyObj = enhancer.create();  
            return proxyObj;// 返回代理对象  
        }  


    @Override
    public Object intercept(Object proxy, Method method, Object[] args,
            MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        System.out.println("动态代理-cglib--代理人安排运动员跑步 " );
        obj = method.invoke(target, args);
        return obj;
    }

}

*Test 测试类

package dailimoshi;

public class Test {
     public static void main(String[] args) {

        IRunner r = new StaticRunnerAgent(new Runner());
        System.out.println("静态代理---有比赛,联系运动员代理");
        r.run();

        System.out.println("---------------------------------");

        System.out.println("jdk动态代理---有比赛,联系运动员代理");
        IRunner dr = (IRunner) new DynamicRunerAgent(new Runner()).getProxy();
        dr.run();


        System.out.println("---------------------------------");

        System.out.println("cglib动态代理---有比赛,联系运动员代理");
        //IRunner cglibr = (IRunner) new CglibRunnerAgent().createProxyObject(new Runner());
        Runner cglibr = (Runner) new CglibRunnerAgent().createProxyObject(new Runner());
        cglibr.run();
    }
}

效果:
这里写图片描述

动态代理指的是在运行时在生成的代理类。
jdk动态代理和cglib的不同是:
jdk动态代理,需要被代理的类有接口;
cglib可以直接代理一个类,无需其有接口,原理是对一个类生成一个子类。所以被final修饰的类,不能继承因而不能用cglib动态代理。

猜你喜欢

转载自blog.csdn.net/u011877584/article/details/81942137
今日推荐