0

我有很多这样的方法:

    Connection connection = null;
    try {
        connection = new Connection();
        connection.connect();
        .... // method body

    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }

我可以将这部分排除在方面(AspectJ)吗?

4

2 回答 2

2

您可以将连接管理提取到环绕建议中,并通过将上下文Connection暴露在ThreadLocal. 定义一个具有静态属性的公共类:

public class ConnectionHolder {
  public static final ThreadLocal<Connection> connection = new ThreadLocal<>();
}

在周围的建议中,您必须将 设置ThreadLocal为打开的连接,并确保之后无条件清除它。这是ThreadLocals 的最大缺陷:将对象泄漏到不相关的上下文中。还要注意继承的子线程ThreadLocal(曾经在 WebSphere 中有一个问题)。

总而言之,ThreadLocals 是一个相当肮脏的解决方案,但其他任何事情都需要您使用像 Spring 这样的依赖注入框架,配置请求范围的 bean 等,这将是一个好主意,但需要更多研究你的部分。

于 2013-02-12T09:25:31.183 回答
0

或者,您可以使用模板模式提取连接管道以避免复制/粘贴。基本思想是这样的:

abstract ConnectionTemplate {
    private Connection connection = // ...

    /**
     * Method to be implementad by child classes
     */
    public abstract void businessLogicCallback(); 

    /**
     * Template method that ensure that mandatory plumbing is executed
     */
    public void doBusinessLogic() {
        try {
            openConnection();
            // fetch single result, iterate across resultset, etc
            businessLogicCallback();
        finally {
            closeConnection();
        }
    }

    void openConnection() {
        connection.open();
    }

    void closeConnection() {
        if (connection != null) {
            connection.close();
        }
    }
}

现在,实现类可以很简单

class ImportantBusinessClass extends ConnectionTemplate {

    @Override
    public void businessLogicCallback() {
        // do something important
    }
}

你像这样使用它

ImportantBusinessClass importantClass = new ImportantBusinessClass();
importantClass.doBusinessLogic();      // opens connection, execute callback and closes connection

Spring 框架在某些地方使用了这种技术,特别是JdbcTemplate处理 SQL、连接、行和域对象之间的映射等。实现细节请参考 GitHub 中的源代码

于 2013-02-12T06:44:30.740 回答