反射知识小结及动态代理

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;
	}
}

这样所有带接口的类的实列对象都可以进行改造了

 

 

 

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