首先,代理模式:就是真正的业务功能还是业务类来实现,但是在实现业务之前的一些公共服务,例如在项目开发中忘记了加入缓冲、日志等的功能。后期想加入,就可以使用代理来实现而没有必要打开已经封装好的委托类。
jdk中的静态代理:
public interface IHelloDao {
void say();
}
public class HelloDao implements IHelloDao{
@Override
public void say() {
System.out.println("hello");
}
}
public class ProxyHello implements IHelloDao {
private IHelloDao userDao;
public ProxyHello(IHelloDao userDao) {
this.userDao = userDao;
}
@Override
public void say() {
System.out.println("before hello");
userDao.say();
System.out.println("after hello");
}
public static void main(String[] args) {
IHelloDao helloDao = new HelloDao();
ProxyHello proxyHello = new ProxyHello(helloDao);
proxyHello.say();
}
}
代理类跟实现类都继承同一个接口即可实现,但是局限性也很大,就是每一个不同的类都会有一个代理类。
jdk中的动态代理
public class ProxyFactory implements InvocationHandler {
// 目标类
private Object targetObject;
public ProxyFactory(Object targetObject) {
this.targetObject = targetObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("berfore hello");
// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
Object result = method.invoke(targetObject, args);
System.out.println("after hello");
return result;
}
public static void main(String[] args) {
IHelloDao helloDao = new HelloDao();
/**
*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
*
*/
IHelloDao proxyHelloDao = (IHelloDao) Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(), new Class[]{IHelloDao.class}, new ProxyFactory(helloDao));
proxyHelloDao.say();
}
}