[JAVA dynamic proxy (2)]

Permalink:  http://gaojingsong.iteye.com/blog/2285271

Preview article: The Proxy Pattern of Design Patterns

 

JDK's built-in Proxy dynamic proxy can dynamically generate bytecode at runtime, without the need to write proxy classes for each class. In the middle, an interface InvocationHandler and Proxy.newProxyInstance static method are mainly used. The parameters are described as follows:

 

The role of the Proxy class is to dynamically create a class of proxy objects. It provides many methods, but the one we use the most is the newProxyInstance method:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException

Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.

The function of this method is to get a dynamic proxy object that receives three parameters. Let's take a look at the meanings of these three parameters:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

loader: A ClassLoader object that defines which ClassLoader object is used to load the generated proxy object

interfaces: an array of Interface objects, which represents a set of interfaces that I will provide to the object I need to proxy. If I provide a set of interfaces to it, then the proxy object declares to implement the interface (polymorphism), This way I can call the methods in this set of interfaces

h: An InvocationHandler object, which indicates which InvocationHandler object will be associated with when my dynamic proxy object calls a method

 

Proxy has been designed very beautifully, but there is still a little regret, that is, it can't get rid of the shackles of only supporting interface proxy, because its design is doomed to this regret.

 

There is a problem with using the built-in Proxy to implement dynamic proxy: the class to be proxied must implement the interface, and there is no way to complete the dynamic proxy without implementing the interface.

If some classes in the project do not implement interfaces, you should not deliberately extract some interfaces that have no instance meaning in order to implement dynamic proxy. This problem can be solved by cglib.

CGLIB (Code Generation Library) is an open source project. It is a powerful, high-performance, high-quality Code generation library. It can extend Java classes and implement Java interfaces at runtime. Generally speaking, cglib can dynamically generate characters at runtime. Section code. cglib is a popular proxy.

 

Steps for usage:

1) Introduce maven coordinates

<dependency>

    <groupId>cglib</groupId>

    <artifactId>cglib</artifactId>

    <version>2.2.2</version>

</dependency>

2) Write business class

3) Develop a proxy class to implement the MethodInterceptor interface

 

The source code example is as follows:

1) Write a business class (you can implement the interface or not)

package demo;

 

//Another ugly queen.

//Wang Po is old and smart, she is too old. Even a man can't look down on her, but she is wise and experienced, and she acts as a kind of woman's agent!

public class WangPo {

  public void makeEyesWithMan() {

      // 这么大年龄了谁看她抛媚眼?!

 System.out.println("王婆抛媚眼..这么大年龄了谁看她抛媚眼?.");

  }

}

2)开发代理类,实现MethodInterceptor接口

package demo;

 

import java.lang.reflect.Method;

 

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

 

/*

 * 动态代理类

 * 实现了一个方法拦截器接口

 */

public class DynamicProxy implements MethodInterceptor {

 

    // 被代理对象

    Object targetObject;

 

    //Generate a new class if necessary and uses the specified callbacks (if any) to create a new object instance. 

    //Uses the no-arg constructor of the superclass.

    //动态生成一个新的类,使用父类的无参构造方法创建一个指定了特定回调的代理实例

    public Object getProxyObject(Object object) {

        this.targetObject = object;

        //增强器,动态代码生成器

        Enhancer enhancer=new Enhancer();

        //回调方法

        enhancer.setCallback(this);

        //设置生成类的父类类型

        enhancer.setSuperclass(targetObject.getClass());

        //动态生成字节码并返回代理对象

        return enhancer.create();

    }

 

    // 拦截方法

    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        // 被织入的横切内容,开始时间 before

        long start = System.currentTimeMillis();

        // 调用方法

        Object result = methodProxy.invoke(targetObject, args);

        // 被织入的横切内容,结束时间

        Long span = System.currentTimeMillis() - start;

        System.out.println("共用时:" + span);

        

        return result;

    }  }

3)测试

package demo;

 

public class DemoMain {

/**

* @param args

*/

public static void main(String[] args) {

//ProxyWomen proxyWomen = new ProxyWomen();

//KindWomen kindWomen = (KindWomen) proxyWomen.bind(new PanJinLian());

//kindWomen.makeEyesWithMan();

 

WangPo wangpo =  (WangPo) new DynamicProxy().getProxyObject(new WangPo());

wangpo.makeEyesWithMan();

}

 

}



 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326779952&siteId=291194637