我有很多这样的方法:
Connection connection = null;
try {
connection = new Connection();
connection.connect();
.... // method body
} finally {
if (connection != null) {
connection.disconnect();
}
}
我可以将此部分排除在方面(AspectJ)吗?
答案 0 :(得分:2)
您可以将连接管理提取到around-advice中,并通过在Connection
中公开它来使业务代码可以使用上下文ThreadLocal
。使用静态属性定义公共类:
public class ConnectionHolder {
public static final ThreadLocal<Connection> connection = new ThreadLocal<>();
}
在周围的建议中,您必须将ThreadLocal
设置为打开的连接,然后确保您之后无条件地将其清除。这是ThreadLocal
s最大的陷阱:将对象泄漏到不相关的上下文中。还要注意继承ThreadLocal
的子线程(在WebSphere中存在一个问题)。
总而言之,ThreadLocal
是一个非常脏的解决方案,但是其他任何东西都需要你去像Spring一样的依赖注入框架,配置请求范围的bean等,这将是一个很好的想法,但会对你进行更多的研究。
答案 1 :(得分:0)
或者,您可以使用template pattern提取连接管道以避免复制/粘贴。基本想法是这样的:
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中的source code以获取实现细节。< / p>