动态代理

上文讲述了静态代理,jdk自身也实现了代理机制----jdk动态代理,需要应用jdk动态代理,需要实现一个接口java.lang.reflect.InvocationHandler,这样生成的动态代理就会自动调用invoke方法。代理要首先创建出来目标对象的代理对象,这个调用Proxy的newProxyInstance方法即可。

类似上文的需求,如果乙需要实现增删改查功能,但是实现之后这些功能要加安全性检查,但是不能动源代码,那么就可以用jdk动态代理实现,但是此时不再用实现与乙一样的接口了,只需要实现InvocationHandler接口即可,由于当业务方法被调用的时候实际都会调用invoke方法,这样在invoke方法中追加安全性检查代码就实现了不动源代码实现功能的目的,代码示例如下:

乙接口:

package com.DynamicProxy;
/**
 * @author 
 *
 * 2012-10-17上午9:37:31
 */
public interface ManagerInterface {
 
 public void add();
 public void delete();
 public void modify();
 public String search();

}

乙实现:

package com.DynamicProxy;
/**
 * @author 
 *
 * 2012-10-17上午9:38:26
 */
public class ManagerImpl implements ManagerInterface {

 public void add() {
  System.out.println("add");
 }

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

 public void modify() {
  System.out.println("modify");
 }

 public String search() {
  System.out.println("search");
  return "search=============================";
 }
}

动态代理:

package com.DynamicProxy;

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

/**
 * @author 
 *
 *         2012-10-17上午10:04:41
 */
public class ManagerProxy implements InvocationHandler {

 Object targetObject;

 public Object newProxy(Object targetObject) {
  this.targetObject = targetObject;
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
    targetObject.getClass().getInterfaces(), this);
 }

 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  checkSecurity();
  Object ret = null;
  try {
   ret = method.invoke(targetObject,args);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return ret;
 }
 
 public void checkSecurity(){
  System.out.println("checkSecurity==============================");
 }
}
客户端代码:

package com.DynamicProxy;
/**
 * @author 
 *
 * 2012-10-17上午10:20:50
 */
public class Client {

 /**
  * @param args
  */
 public static void main(String[] args) {
  ManagerImpl managerImpl = new ManagerImpl();
  ManagerProxy managerProxy = new ManagerProxy();
  ManagerInterface managerInterface = (ManagerInterface)managerProxy.newProxy(managerImpl);
  managerInterface.add();
  managerInterface.delete();
  managerInterface.modify();
  System.out.println(managerInterface.search());

 }

}
需要注意的是

调用invoke方法时候的第一个参数为目标对象引用,如果此处直接 method.invoke(proxy,args);就会有问题了,proxy是jdk为你生成的代理类的实例,实际上就是使用代理之后adder引用所指向的对象。由于我们调用了managerInterface.add(),才使得invoke()执行,如果在invoke()中使用method.invoke(proxy, args),那么又会使invoke()执行。没错,这是个死循环。

 

具体代码见附件。

你可能感兴趣的:(动态代理,JDK动态代理,procy)