public class Client {
public static void main(final String[] args) throws Exception {
new UsingA() { A r1 = new A("r1"); {
new UsingB() { B r2 = new B("r2"); {
new UsingA() { A r3 = new A("r3"); {
r1.use("x");
r2.use("y");
r3.use("z");
}};
}};
}};
}
}、、、自動的に r3, r2, r1 の順にリソースが解放されるようにしてみたい。(前回までのコードでは r1 が解放されず r3 が2度解放されてしまっていた。)
以下のように Stack を使って UsingAspect を修正。ついでにマルチスレッドで使えるように percflow(using()) をアスペクト定義に付与。
public abstract aspect UsingAspect<T, U> percflow(using()) {
protected Stack<T> stack = new Stack<T>();
pointcut settingField(T o): set (T+ U+.*) && args(o);
pointcut using(): call(U+.new(..));
after(T o): settingField(o) {
this.stack.push(o);
}
after(): using() {
if (!stack.empty()) endUsing(this.stack.pop());
}
protected abstract void endUsing(T o);
}
その他のクラスは、ほとんど自明だけど以下のようなものになる。
UsingA
public interface UsingA {
public static aspect AspectA
extends UsingAspect<A, UsingA> {
@Override
public void endUsing(A o) {
if (null != o) o.dispose();
}
}
}
UsingB
public interface UsingB {
public static aspect AspectB
extends UsingAspect<B, UsingB> {
@Override
public void endUsing(B o) {
if (null != o) o.close();
}
}
}
A
public class A {
private final String name;
public A(String name) {
this.name = name;
}
public void dispose() {
System.out.printf("%s disposed%n", this);
}
public void use(String str) {
System.out.printf("%s used with \"%s\"%n", this, str);
}
public String toString() {
return String.format("A(\"%s\")", this.name);
}
}
B
public class B {
private final String name;
public B(String name) {
this.name = name;
}
public void close() {
System.out.printf("%s closed%n", this);
}
public void use(String str) {
System.out.printf("%s used with \"%s\"%n", this, str);
}
public String toString() {
return String.format("B(\"%s\")", this.name);
}
}
実行すると以下のようなコンソール出力を得る。A("r1") used with "x"
B("r2") used with "y"
A("r3") used with "z"
A("r3") disposed
B("r2") closed
A("r1") disposed
割と簡単に using のネストができた。一応、だんだんと実用的になってきた気がする。取りあえずテストコードで使い始めて、パフォーマンスなんかを中心にしばらく観察してから、問題が無ければプロダクトコードで使ってみるような流れで良いか。
0 件のコメント:
コメントを投稿