关于Jdk中的静态代理跟动态代理

178 阅读1分钟

首先,代理模式:就是真正的业务功能还是业务类来实现,但是在实现业务之前的一些公共服务,例如在项目开发中忘记了加入缓冲、日志等的功能。后期想加入,就可以使用代理来实现而没有必要打开已经封装好的委托类。


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();
    }
}