A-A+

Java Proxy的小结

2020年06月28日 技术, 默认 暂无评论 阅读 1,154 次

最近太热了,北京的疫情又有所反弹,天天戴个大口罩子,什么事情都不想干了,只想大字型躺在床上——保持呼吸。

今天稍微能够提振心情,简单的记录一下我最近的内部分享,有兴趣的看官凑合读读吧。

首先从静态代理说起。

静态代理的例子分为几步:

1. 声明个接口(I)。   

2. 创建个实现类(A),实现接口。

3. 创建个实现类(B),实现接口,同时构造函数的参数类型为接口(I)。

4. B中的实现方法,最终调用的是A的实现方法。

用代码来说就是:

接口(I):

public interface IUserDao {
    void saveUser();

    void editUser(String id);
}

实现类(A):

public class UserDao implements IUserDao {

    @Override
    public void saveUser() {
        System.out.println("保存");
    }

    @Override
    public void editUser(String id) {
        System.out.println(id);
    }
}

实现类(B):

public class UserProxyDao implements IUserDao {

    private IUserDao userDao;

    public UserProxyDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void saveUser() {
        userDao.saveUser();
    }

    @Override
    public void editUser(String id) {
        System.out.println("在editUser之前");
        userDao.editUser(id);
        System.out.println("在editUser之后");
    }
}

测试一下:

public static void main(String[] args) {
    UserProxyDao userProxyDao = new UserProxyDao(new UserDao());
    userProxyDao.editUser("1");
}

总结:

没什么难以理解的,要是不怕麻烦,声明百八十个类,就能把想干的事干了。

不过,程序员不就是一帮懒的不能再懒的人,总想一劳永逸,于是就有了动态代理。

本文以JDK动态代理来说明。动态代理就是把实现类(B)搞成通用的,构造函数里面传个A,就给返回A的实例化对象。如果传入了个C,就返回C的实例化对象。

怎么实现呢,代码也挺简单的:

public class ProxyFactory {

    private Object object;

    public ProxyFactory(Object object) {
        this.object = object;
    }

    public Object getInstance() {
        return Proxy.newProxyInstance(
                object.getClass().getClassLoader(),
                object.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("在" + method.getName() + "之前");
                        Object returnValue = method.invoke(object, args);
                        System.out.println("在" + method.getName() + "之后");
                        return returnValue;
                    }
                });
    }
}

测试一下:

public static void main(String[] args) {
    //可以随便扔进去对象了
    ProxyFactory proxyFactory = new ProxyFactory(new UserDao());
    IUserDao userDao = (IUserDao) proxyFactory.getInstance();
    userDao.editUser("1");
}

到这里,就可以发挥脑洞去想想Spring是怎么实现对象代理的。

有兴趣的话可以看看:

org.springframework.aop.framework.DefaultAopProxyFactory

老规矩,如有问题,欢迎指正。太热了,还是大字型继续躺着吧。

觉的不错?可以关注我的公众号↑↑↑

给我留言

Copyright © 字痕随行 保留所有权利.   Theme  Ality

用户登录

分享到: