java如何使用代理实现这个业务场景?

发布于 2022-09-03 23:54:19 字数 2401 浏览 13 评论 0

我想写一个数据库连接池来为其他数据库访问类提供Connection, 但是我这个数据库连接池的产生是在数据库访问类写完之后, 因此所有的访问在结尾都有Connection.close()的调用, 因此我就在想, 当调用connection.close()时, 将该connection加入数据库连接池中. 所以我就写了一个代理类, 但是想的很美, 写起来就不知道该怎么写了. 如何将这个proxy产生的代理对象加入连接池中呢?

我目前的实现如下:

class EmptyInvocationHandler implements InvocationHandler{
    private EmptyConnection emptyConnection ;
    private ConnectionPool connectionPool ;

    public EmptyInvocationHandler(EmptyConnection emptyConnection ,ConnectionPool connectionPool) {
        this.connectionPool = connectionPool ;
        this.emptyConnection = emptyConnection;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(method.getName().equals("close")){
            close();
            return null ;
        }
        else
            return method.invoke(emptyConnection , args) ;
    }
    //如果这样实现的话, 就是把真实的对象加入了连接池中, 如何把这个代理对象加入池中呢?
    private void close(){
        connectionPool.recycleConnection(emptyConnection);
    }
}

//模拟Connecter接口
interface EmptyConnectionI{
    void doSomething() ;
    void close() ;
}

//connecter的默认实现
class EmptyConnection implements EmptyConnectionI{
    public void doSomething(){
        System.out.println("do something");
    }

    public void close(){
        System.out.println("real close");
    }
}

class ConnectionPool{
    private List<EmptyConnectionI> list = new ArrayList<>() ;
    private boolean inited = false ;
    public EmptyConnectionI getConnection(){
        if(!inited)
            init() ;
        return list.remove(0) ;
    }

    private void init(){
        EmptyConnection emptyConnection = new EmptyConnection() ;
        try {
            Class proxyClass = Proxy.getProxyClass(EmptyConnection.class.getClassLoader()
                    , new Class[]{EmptyConnectionI.class});
            EmptyConnectionI emptyConnectionI = (EmptyConnectionI) proxyClass.getConstructor(new Class[]{InvocationHandler.class})
                    .newInstance(new EmptyInvocationHandler(emptyConnection, this));
            list.add(emptyConnectionI) ;
        }
        catch (Exception e){
            e.printStackTrace();
            System.exit(-1);
        }
    }

    public void recycleConnection(EmptyConnectionI connection){
        list.add(connection) ;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

溺渁∝ 2022-09-10 23:54:19

你怎么知道什么时候是需要close连接?

煮酒 2022-09-10 23:54:19

可以实现的,MyBatis的PooledConnection和PooledDataSource这两个类就做了这样的事情,先标个记,回头写篇这两个类的源码分析文章再贴回来。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文