http://blog.csdn.net/giserstone/article/details/17199755
动态代理:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
1.首先定义一个接口Person.java
package cn.java.study.proxy;
public interface Person {
String getDescription();
void setName(String name);
}
2.分别让Student,Runner引用Person
package cn.java.study.proxy;
public class Student implements Person{
private String name;
private int age;
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return "type:student name:" + name + " age:" + age;
}
public static void main(String[] args){
Person person = new Student("Luccy", 10);
person.getDescription();
System.out.println("description:" + person.getDescription());
}
}
package cn.java.study.proxy;
public class Runner implements Person {
private String name;
private int age;
public Runner() {
super();
}
public Runner(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return "type:runner name:" + name + " age:" + age;
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
this.name = name;
}
}
3.定义一个PersonInvocationHandler并继承InvocationHandler
package cn.java.study.proxy;
import java.lang.reflect.Method;
/**
* 动态代理类对应的调用处理程序类
* @author lk
*/
public class PersonInvocationHandler implements java.lang.reflect.InvocationHandler {
//代理类持有一个委托类的对象引用
private Object delegate;
public PersonInvocationHandler(Object delegate) {
super();
this.delegate = delegate;
}
// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 利用反射机制讲请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。
Object obj = method.invoke(delegate, args);
return obj;
}
}
4.生成动态代理对象的工厂方法
package cn.java.study.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* 生成动态代理对象的工厂
* @author lk
*
*/
public class DynProxyFactory {
public static final int STUDENT = 1;
public static final int RUNNER = 2;
//客户类调用此工厂方法获得代理对象。
//对客户类来说,其并不知道返回的是代理类对象还是委托类对象。
public static Person getInstance(int type){
Person deletage = null;
switch(type){
case STUDENT:
deletage = new Student();
break;
case RUNNER:
deletage = new Runner();
break;
}
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
InvocationHandler handler = new PersonInvocationHandler(deletage);
// 通过 Proxy 直接创建动态代理类实例
Person proxy = (Person) Proxy.newProxyInstance(
deletage.getClass().getClassLoader(),
deletage.getClass().getInterfaces(),
handler);
return proxy;
}
}
5.使用
package cn.java.study.proxy;
public class Client {
public static void main(String[] args){
doSomething(DynProxyFactory.STUDENT);
doSomething(DynProxyFactory.RUNNER);
}
private static void doSomething(int type) {
Person proxy = DynProxyFactory.getInstance(type);
proxy.setName("stu" + type);
String des = proxy.getDescription();
System.out.println(des);
}
}