码迷,mamicode.com
首页 > 其他好文 > 详细

动态代理

时间:2018-05-15 22:52:24      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:tin   执行   stat   err   ssl   main   apt   测试   moc   

JDK动态代理

JDK动态代理主要用到Proxy类和InvocationHandler接口,通过使用他们就可以生成JDK动态代理类和动态代理对象。
Proxy提供如下两个方法创建动态代理类和动态代理实例。

  • public static Class<?> getProxyClass(ClassLoader loader,Class<?>...interfaces):创建一个动态代理类对应的Clas对象,该代理类将实现了interfaces接口。第一个Classloader参数指生成被代理类或接口的类加载器。

  • public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h):直接创建一个动态代理对象,该代理对象的实现类实现了interfaces所指定的接口,执行代理对象的每个方法都会被替换执行InvocationHandler对象的invoke方法。

下面作了一个演示,其中对象foo是由ProxygetProxyClass方法先创建一个动态代理类的Clas对象,再创建动态代理实例,对象foo1是由ProxynewProxyInstance直接创建一个动态代理实例。

/**
 * Created by SqMax on 2018/4/25.
 */
interface Foo {
    void info();
}

public class ProxyClassTest {

    public static void main(String[] args) throws Exception {
        Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(),
                new Class[]{Foo.class});
        Constructor constructor = proxyClass.getConstructor(new Class[]{InvocationHandler.class});
        Foo foo = (Foo) constructor.newInstance(new Object[]{
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("executing method:" + method);
                        return null;
                    }
                }
        });
        Foo foo1 = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("executing method:" + method);
                        return null;
                    }
                });
        foo.info();
        foo1.info();
    }
}

上面程序执行结果如下:

executing method:public abstract void top.sqmax.chapter18.Foo.info()
executing method:public abstract void top.sqmax.chapter18.Foo.info()

动态代理与AOP

有如下接口和类:

public interface Dog {
    void info();
    void run();
}
public class GunDog implements Dog {
    @Override
    public void info() {
        System.out.println("i am a gundog.");
    }

    @Override
    public void run() {
        System.out.println("i am running.");
    }
}

想要在GunDog的info和run方法执行前和执行后执行一些通用的动作method1,method2()。

public class DogUtil {
    public void method1(){
        System.out.println("---mock first common method---");
    }
    public void method2(){
        System.out.println("---mock second common method2----");
    }
}

可以使用动态代理。

public class MyProxyFactory {
    public static Object getProxy(Object target){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),new InvocationHandler(){
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        DogUtil du=new DogUtil();
                        du.method1();
                        Object result=method.invoke(target,args);
                        du.method2();
                        return result;
                    }
                });
    }
}

下面测试,生成对GunDog的动态代理实例。

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

        Dog target = new GunDog();
        Dog dog = (Dog) MyProxyFactory.getProxy(target);
        dog.info();
        dog.run();
    }
}

执行结果

---mock first common method---
i am a gundog.
---mock second common method2----
---mock first common method---
i am running.
---mock second common method2----

cglib动态代理

稍后补充.......

动态代理

标签:tin   执行   stat   err   ssl   main   apt   测试   moc   

原文地址:https://www.cnblogs.com/sqmax/p/9042868.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!