静态代理
例子:有一个教师类,教师类有一个教书方法
需要使用一个代理类来代理教师,将教师类聚合到代理类里面
具体代码如下:
首先创建一个接口,不仅教师类需要实现,代理类也需要实现,但是注意的是,代理类实现的时候,是使用的教师类的教书方法。
package com.StaticProxy;//代理模式
public interface ITeacherDao {void teach();
}
package com.StaticProxy;//真正的实体对象,需要被代理的类
//该类中有真正的教书方法
public class TeacherDao implements ITeacherDao {private String name;public void setName(String name) {this.name = name;}@Overridepublic void teach() {System.out.println(this.name + "在教书");}
}
package com.StaticProxy;//代理,需要代理TeacherDao,它虽然有teach方法,但是不是真的会教书,所以需要调用TeacherDao的教书方法
public class TeacherDaoProxy implements ITeacherDao{private ITeacherDao teacherDao;public TeacherDaoProxy(ITeacherDao teacherDao) {this.teacherDao = teacherDao;}@Overridepublic void teach() {System.out.println("通过代理对象。。。");System.out.println("代理使用真实的teacherDao在教书");teacherDao.teach();System.out.println("代理结束");}
}
使用代理类:
package com.StaticProxy;public class Client {public static void main(String[] args) {//新建一个TeacherDAO类TeacherDao teacherDao = new TeacherDao();teacherDao.setName("lisi");//使用一个代理类来代理教师类TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);teacherDaoProxy.teach();}
}
因为是静态代理,所以就是教师代理类,要是换一个需要代理的类,就不能实现了。一次引入动态代理。
动态代理
使用一个proxyFactory,传入一个Target目标对象,动态生成对应的目标代理对象。
首先需要一个目标对象类的接口。
package com.DynamicProxy;public interface ITeacherDao {void teach();
}
目标对象类实现这个接口。
package com.DynamicProxy;public class TeacherDao implements ITeacherDao{private String name;public void setName(String name) {this.name = name;}@Overridepublic void teach() {System.out.println(this.name + "在教书");}
}
动态代理工厂
在该类中,使用Proxy.newProxyInstance,生成代理对象,这个方法有3个参数:
- ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
- Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
- InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
package com.DynamicProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyFactory {//维护一个目标对象,object 这里相当于TeacherDao了private Object target;//构造器,对target进行初始化public ProxyFactory(Object target){this.target = target;}//给目标对象 生成一个代理对象// ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
// Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
// InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入public Object getProxyInstance(){return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("jdk代理开始---");//反射机制调用目标对象的方法Object returnVal = method.invoke(target, args);return returnVal;}});}
}
package com.DynamicProxy;import com.DynamicProxy.TeacherDao;public class Client {public static void main(String[] args) {//目标对象
// ITeacherDao teacherDao = new TeacherDao();TeacherDao teacherDao = new TeacherDao();teacherDao.setName("lisi");//使用代理工厂 给目标对象创建代理对象ProxyFactory proxyFactory = new ProxyFactory(teacherDao);//强转成ITeacherDao类型 否则没办法调用教书方法ITeacherDao proxyInstance =(ITeacherDao) proxyFactory.getProxyInstance();//proxyInstance : class com.sun.proxy.$Proxy0 内存中动态生成了代理对象proxyInstance.teach();}
}