java反射机制&Annotation详解_II


JDK动态代理和CGlib动态代理



1.JDK动态代理


JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。

接口1  Man.java
//接口1
public interface Man {
 
 public void work();  
    
    public void run();  
}


接口2  Women.java

//接口2
public interface Women {
 
 public  void shopping();  
}


实现接口类Person.java  

public class People implements Man, Women {

 public void run() {
  System.out.println("男人:兄弟快跑第二季");
 }
 public void work() {
  System.out.println("男人:努力工作");
 }
 public void shopping() {
  System.out.println("女人:打扮漂漂亮亮的");
 }
}


代理类  DynamicProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxy implements InvocationHandler {

 // 需要被代理类的引用
 private Object object;

 // 构造方法
 public DynamicProxy(Object object) {
  this.object = object;
 }

 public Object getProxy() {
  //通过Proxy类的newProxyInstance方法动态生成一个动态代理,并返回它
  //java还让这个动态生成的$Proxy0类实现了要代理类的实现的所有接口,并继承了Proxy接口。 
  //得到的其实是一个类名叫$Proxy0 extends Proxy implements ***Interface的类
  return Proxy.newProxyInstance(object.getClass().getClassLoader(),
    object.getClass().getInterfaces(), this);
 }
   
 //重写invoke方法,这里处理真正的方法调用
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  beforeDoing();
  
  Object invoke=method.invoke(object, args);
  
  afterDoing();
  
  return invoke;
 }
 
 public void beforeDoing(){
  System.out.println("-------------before---------------");
 }
 public void afterDoing(){
  System.out.println("-------------after----------------");
 }
}


测试类  Test.java
public static void main(String[] args) {
   People realSubject=new People();
   
   DynamicProxy dynamicProxy=new DynamicProxy(realSubject);

   Man man=(Man) dynamicProxy.getProxy();
   man.work();
   man.run();
   
   Women women=(Women)dynamicProxy.getProxy();
   women.shopping();
 }


运行结果

-------------before---------------
男人:努力工作
-------------after----------------
-------------before---------------
男人:兄弟快跑第二季
-------------after----------------
-------------before---------------
女人:打扮漂漂亮亮的
-------------after---------------- 


2.CGlib动态代理

CGLIB是一个强大的高性能的 代码生成 包。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)。EasyMock和 jMock 是通过使用模仿(mock)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(mock)对象。

实现类 Man.java 

public class Man {
	
	public void work(){
		System.out.println("要去上班咯");
	}
}

代理类Cglib.java

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 Cglib implements MethodInterceptor {

	private Object target;
	
	public Object getInstance(Object target){
		this.target=target;
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		//回调方法
		enhancer.setCallback(this);
		//创建代理对象
		return enhancer.create();
	}
	
	/**
	 * 拦截器,在这里你可以为所欲为
	 */
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		 System.out.println("----上班之前打卡------");
		 proxy.invokeSuper(obj, args);
		 System.out.println("----上班后打球去-------");
		 return null;
	}
}

测试类Test.java  

public class Test {

	public static void main(String[] args) {
		// 代理类
		Cglib cglib = new Cglib();

		// 实现类
		Man impl = (Man) cglib.getInstance(new Man());
		impl.work();
	}
}

运行结果:

----上班之前打卡------
要去上班咯
----上班后打球去------- 



参考博客: http://blog.csdn.net/hintcnuie/article/details/10954631
                http://www.iteye.com/topic/683613/

我是菜鸟,我在路上。 
2015年5月28日14:49:44


你可能感兴趣的:(动态代理,反射,proxy,cglib)