反射知識小結及動態代理

1.獲得類對象的三種方法

Class clazz=Class.forName(全類名);
Class clazz=Person.class;
Class clazz=person.getClass();

2.通過類對象獲得實列

clazz.newInstance()    此種是採用無參構造器,構造實列,如果沒有無參構造器或者想通過特定的有參構造器構造實例,可以通過下面方式

Class clazz=Class.forName("cn.zw.learn.test.Student");
Constructor constructor =clazz.getConstructor(String.class,Integer.class);
Student student=(Student) constructor.newInstance("zhaoei",22);
System.out.println(student);

3.反射獲取成員變量並使用

        Student student=new Student("張", 22);
		Class clazz=student.getClass();
		Field field = clazz.getDeclaredField("name");
		field.setAccessible(true);
        field.set(student,"zhao")
		System.out.println(student);        

4.反射獲取方法並執行

        Student student=new Student("張", 22);
		Class clazz=student.getClass();
		Method method=clazz.getMethod("show",String.class);
	    method.invoke(student, "zhao");

   註釋:對於 field.set(student,"zhao") 和 method.invoke(student, "zhao"),傳入的對象可以是Student類的任何實例,作用還是   挺大的

5.動態代理的實現

首先動態代理有毛用?

動態代理主要用於給批量方法添加模式化的操作而使用,比如日誌、數據庫日誌管理

也就是將原來的類的每個方法或者帶有某些特性的方法進行加入特定模式操作的改造使他生成一個新的類

java提供了這個proxy還有其改造的方法

Proxy.newProxyInstance(loader, interfaces, h)

有三參數,第一參數該類的類加載器,第二個參數該類的接口,第三個參數實現了InvocationHandler的對該類的改造類,就是你要怎麼改造,前兩個參數好說,通過類對象都能獲得,主要是第三個參數改造類,我們既然要改造實列的方法我們可以把原來的方法外面包一層,這樣類外層之間就可以加我們要寫的代碼了

代碼如下

接口

public interface Person {
	public void show();
}

具體的原來的類

public class Worker implements Person {

	public void show() {

		System.out.println("幹活幹活幹活。。。。。");

	}

}

改造類

public class MyInvocationHandler implements InvocationHandler {
	
	private Person person;
	
	public MyInvocationHandler(Person person) {
		this.person=person;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("幹活之前要拿工具");
		method.invoke(person, args);
		System.out.println("幹活之後要收拾工具");
		return null;
	}

}

運行測試

    @Test
public void test7()throws Exception{
    Worker worker=new Worker();
    worker.show();
    System.out.println("----------");
    Class clazz=worker.getClass();
	Person person=(Person) Proxy.newProxyInstance(clazz.getClassLoader(), 
       clazz.getInterfaces(), new MyInvocationHandler(worker));
	person.show();	
		
	}

 

運行結果

幹活幹活幹活。。。。。
----------
幹活之前要拿工具
幹活幹活幹活。。。。。
幹活之後要收拾工具

這樣便從原來的方法上進行了改造

想想工廠裏面生產線,是這邊放原材料那邊出產品於是我們組裝組裝成如下的樣子

public class ProxyTool implements InvocationHandler {
    private Object  target;	
	public Object getInstance(Object target){
	        this.target=target;
		Class clazz=target.getClass();
		return  Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);		
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//在這裏可以寫處理的事情
		System.out.println("幹活之前要拿工具");
		method.invoke(target, args);		
		//在這裏也可以寫處理的事情
		System.out.println("幹活之前要放工具");
		return null;
	}
}

這樣所有帶接口的類的實列對象都可以進行改造了

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章