代理的作用:可以在不修改别代理对象代码的基础上,通过扩展代理类,进行一些功能的附加与增强。
·接口
public interface Subject {
void doSomeThing();
}
·真实类
public class RelSubject implements Subject{
@Override
public void doSomeThing() {
// TODO Auto-generated method stub
System.out.println("I am doing my homework");
}
}
代理RelSubject类扩展doSomeThing()方法。
一、静态代理
面向接口编程,代理类和真实类继承自同一个接口(或同一个类)
public class StaticProxy implements Subject{
Subject subject = new RelSubject();
@Override
public void doSomeThing() {
// TODO Auto-generated method stub
before();
subject.doSomeThing();
after();
}
private void before() {
System.out.println("放学了!开始写作业!");
}
private void after() {
System.out.println("写完作业了!睡觉!");
}
}
启动类:
public class Application {
public static void main(String[] args) {
System.out.println("===================静态代理==============");
Subject subject = new StaticProxy();
subject.doSomeThing();
}
}
控制台输出:
===================静态代理==============
放学了!开始写作业!
I am doing my homework
写完作业了!睡觉!
二、动态代理
动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy implements InvocationHandler {
private Object tar;
public Object bind(Object tar) {
this.tar = tar;
return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object result = null;
System.out.println("放学了!开始写作业!"); // 在调用具体函数方法前,执行功能扩展
result = method.invoke(tar, args);
System.out.println("写完作业了!开始睡觉!");// 在调用具体函数方法后,执行功能处理
return result;
}
}
启动类:
public class Application {
public static void main(String[] args) {
System.out.println("===================动态代理==============");
DynamicProxy dynamicProxy = new DynamicProxy();
Subject subject2 = (Subject) dynamicProxy.bind(new RelSubject());
subject2.doSomeThing();
}
}
控制台输出:
===================动态代理==============
放学了!开始写作业!
I am doing my homework
写完作业了!开始睡觉!
动态代理使我们免于去重写接口中的方法,而着重于去扩展相应的功能或是方法的增强,与静态代理相比简单了不少,减少了项目中的业务量。
/**
*
* @param loader 类加载器,定义了由哪个classloader对象对生成的代理类进行加载
* @param interfaces 表示我们将要给我们的代理对象提供一组什么样的接口,如果我们提供了这样一
个接口对象数组,那么也就是声明了代理类实现了这些接口,代理类就可以调
用接口中声明的所有方法。
* @param h 一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个
InvocationHandler对象上,并最终由其调用。
* @return
*/
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
- proxy为代理对象
- method为代理对象调用的方法
- args为方法中对应的参数