静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者继承相同的父类
创建教师接口(Teacher),主要方法是:teach()
public interface Teacher { void teach();//授课的方法 }
目标对象(被代理对象)实现教师接口。
public class TeacherImpl implements Teacher { @Override public void teach() { System.out.println("老师授课中。。。"); } }
代理对象实现Teacher接口,并将目标对象传入代理对象中
//代理对象 静态代理 public class TeacherProxy implements Teacher { private Teacher target;//目标对象,通过接口来聚合 //构造器 public TeacherProxy(Teacher target) { this.target = target; } @Override public void teach() { System.out.println("代理对象开始代理。。。。"); target.teach(); System.out.println("提交。。。"); } }
客户端调用
//静态代理 public class Client { public static void main(String[] args) { //创建目标对象 被代理对象 TeacherImpl target = new TeacherImpl(); //创建被代理对象 同时将被代理对象传递给代理对象 TeacherProxy teacherProxy = new TeacherProxy(target); //通过代理对象,调用到被代理对象的方法 teacherProxy.teach(); } }
静态代理优缺点:
//ClassLoader :指定当前目标对象使用的类加载器,类加载器的获取方法固定 //Class<?>[] :目标对象实现的接口类型,使用泛型方法确认类型 //InvocationHandler :事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为参数传入 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
//教师对象接口 public interface Teacher { void teach(String name); } //目标对象实现类 public class TeacherImpl implements Teacher { public TeacherImpl() { } public void teach(String name) { System.out.println(name+"老师正在上课。。。"); } }
创建代理对象
public class DynamicProxy { private Teacher teacher; public DynamicProxy(Teacher teacher) { this.teacher = teacher; } /** * 利用jdk动态创建代理对象 */ public Teacher getProxyObj(){ return (Teacher) Proxy.newProxyInstance(teacher.getClass().getClassLoader(), teacher.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK动态代理准备。。。"); Object invoke = method.invoke(teacher, args); System.out.println("代理完成。"); return invoke; } }); } }
客户端调用
//创建目标对象 Teacher target = new TeacherImpl(); DynamicProxy proxy = new DynamicProxy(target); //创建代理对象 Teacher proxyObj = proxy.getProxyObj(); proxyObj.teach("Tom");
注意:
目标类
public class Teacher { public String teach(){ System.out.println("老师上课了。。。"); return "Hello"; } }
创建代理工厂对象,生成代理对象
public class ProxyFactory implements MethodInterceptor { private Teacher teacher; public ProxyFactory(Teacher teacher) { this.teacher = teacher; } //返回一个代理对象 : 是teacher对象的代理对象 public Object getProxyObj(){ //创建工具类 Enhancer enhancer = new Enhancer(); //设置父类 enhancer.setSuperclass(teacher.getClass()); //设置回调函数 enhancer.setCallback(this); //创建子类对象即代理对象 return enhancer.create(); } //重写intercept方法 会调用目标对象的方法 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib动态代理 准备就绪。。。"); Object invoke = method.invoke(teacher, objects); System.out.println("cglib动态代理 结束"); return invoke; } }
客户端调用
Teacher target = new Teacher(); //获取代理对象 ProxyFactory proxyFactory = new ProxyFactory(target); Teacher proxyObj = (Teacher) proxyFactory.getProxyObj(); //代理对象调用目标对象方法 String s = proxyObj.teach(); System.out.println(s);