1. 程式人生 > >JDK動態代理

JDK動態代理

param ati ide null pop system handler mic cto

http://rejoy.iteye.com/blog/1627405

這篇文章說的夠具體了。可是對比傳智播客那個視頻。貌似有點問題。

return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),   
                target.getClass().getInterfaces(), this); 

上面的類載入器,視頻中推薦是用目標對象的類載入器。

return Proxy.newProxyInstance(target.getClass.getClassLoader().getContextClassLoader(),   
                target.getClass().getInterfaces(), this); 

還有,把那個代理類改個名字好點,改成某某工廠類,不然聽著怪難受的。

package dynamic.proxy;   
  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
  
/** 
 * 實現自己的InvocationHandler 
 * @author zyb 
 * @since 2012-8-9 
 * 
 */  
public class MyInvocationHandler implements InvocationHandler {  
      
    // 目標對象   
    private Object target;  
      
    /** 
     * 構造方法 
     * @param target 目標對象  
     */  
    public MyInvocationHandler(Object target) {  
        super();  
        this.target = target;  
    }  
  
  
    /** 
     * 運行目標對象的方法 
     */  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
          
        // 在目標對象的方法運行之前簡單的打印一下  
        System.out.println("------------------before------------------");  
          
        // 運行目標對象的方法  
        Object result = method.invoke(target, args);  
          
        // 在目標對象的方法運行之後簡單的打印一下  
        System.out.println("-------------------after------------------");  
          
        return result;  
    }  
  
    /** 
     * 獲取目標對象的代理對象 
     * @return 代理對象 
     */  
    public Object getProxy() {  
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),   
                target.getClass().getInterfaces(), this);  
    }  
} 

改成:

package cn.itcast.service.impl;

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



/**
 * @author Administrator
 * JDK動態代理工廠。依據目標對象生成代理對象
 */
public class JDKProxyFactory implements InvocationHandler{
	//要代理的對象
	private Object targetObject;
	//負責生成代理對象的工廠方法
	public Object createProxyObject(Object object){
		//生成PersonServiceBean的代理對象
		this.targetObject = object;
		Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
		return null;
	}
	//代理對象。在獲知要調用目標對象的方法時,會回調該方法。在該方法中,代理對象要把對目標對象的操作,委派目標對象運行。
	/*
	 * 有一臺打印機(目標對象)實現3C標準(接口,沒有質量保證。誰敢用),具有打印功能(方法)。
	 * 有一個會操作打印機的人(代理對象),店主。
	 * 如今有人來打印,就叫店主幫他打印。店主知道了客人要求要打印(請求)
	 * 但是店主自己本身不能打印啊(會打印還得了),核對一下打印的文件(打印前),
	 * 僅僅能給打印機輸入打印指令和參數,讓他進行打印(委派目標對象進行處理),收集文件(打印後)
	 * 
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result ;
		// TODO Auto-generated method stub
		System.out.println("目標對象運行方法前");
		result = method.invoke(targetObject, args);
		System.out.println("目標對象運行方法後");
		return result;
	}
}
測試代碼:

package junit.test;

import static org.junit.Assert.*;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.itcast.service.PersonService;
import cn.itcast.service.impl.JDKProxyFactory;
import cn.itcast.service.impl.PersonServiceBean;

public class SpringTest {

	@Test
	public void jdkProxyTest(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
		PersonService bean = (PersonServiceBean)ctx.getBean("personService1");
		//這裏就不同過容器進行創建PersonService了
		JDKProxyFactory jf = new JDKProxyFactory();
		//由於代理對象實現了目標對象的全部接口,所以也能夠生產的代理對象也是能夠賦值給PersonSercvice
		PersonService personService2 = (PersonService) jf.createProxyObject(bean);
		personService2.save();
	}
}



JDK動態代理