Javaエージェントメカニズムの概要


エージェントはjavaにとって非常に重要なメカニズムであり、もう一つは反射に属していると言えます.jdkでは反射APIについて単独で述べた(java.lang.reflect)反射は資源消費に強いと考える人もいるかもしれませんが、確かに、反射は資源を消費するに違いありませんが、何でも反射に使うわけではありません.だから、最適な試験は資源消費の程度と反射の使用の程度の間にバランスを見つけるべきです.本稿では反射について話すつもりはありません.反射についての心得は後で貼り付けます.自分も最近苦しめている
エージェントは、StaticProxyとDynamicProxyに分けられます.
例:
Package xyz; 
import java.util.logging.* 
public class talkToSomebody{ 
private Logger logger=Logger.getLogger(this.getClass().getName()); 
public void talk(String name){ 
logger.log(Level.INFO,"talking start...."); 
System.out.println("Hi!ni hao,"+name); 
logger.log(Level.INFO,"talking ends...."); 
} 
} 

とても表示して、あなたはtalkの他の人を必要として、実は1つの文だけが肝心で、“Hi!ni hao XXX”、これこそ関係が必要です.あるいはコアビジネスと呼ぶ(今回はちょっと無理かもしれませんが)、誰と話したか、いつから始まったか、いつ終わったかを記録するには、ログ機能がこれを実現します.これはビジネスロジックに属し、ビジネスロジックとコアビジネスを一緒に置いて、いつ記録する必要がなければ、どうしますか.ソースコードを再変更しなければなりません.お客様がコンパイルしたclassやインタフェース、あなたはとても憂鬱です!
解決方法:
Proxyメカニズムを使って、実は代理店は仲介機関のようで、私自身は突然何か(あるいはいやなこと)があって、仲介機関を探してして、もちろんあなたは仲介機関にお金を出さなければなりません.
public interface ITalk{ 
public void talk(String name); 
} 

これをあなたの要求と見なすことができて、仲介機関はあなたの要求に従ってしなければならなくて、あなたはやっと仲介機関にお金を払うことができます;
public class TalkToSomebody implements ITalk{ 
public void talk(String name){ 
System.out.println("Hi,ni hao,"+name); 
} 
} 
はいいですね.仲介機関は私の要求に従って実現しました.結果は間違いありません.

public class StaticProxyTalk Implements ITalk{ 
private Logger logger=Logger.getLogger(this.getClass().getName()); 
private ITalk somebody; 
public StaticProxyTalk(ITalk somebody){ 
this.somebody=somebody; 
} 
public void talk(String name){ 
log("talking start...."); 
somebody.talk(name); 
log("talking ending..."); 
} 
private void log(String message){ 
logger.log(Level.INFO,message) 
} 


気分がよくなりました.これから仲介サービスは必要ありません.彼を探しに行かなければいいです.今、この仲介機関がどうしているか見て、私の要求に達しましたか.
public class TestProxy{ 
public static void main(String []args){ 
ITalk proxy=new StaticProxyTalk(new TalkToSomebody()); 
proxy.talk("HuYong"); 
} 
} 

はい、できました.お金を払ってもいいです.
しかし問題はやはり存在して、もし私がN多くの事がすべて自分でしたくない(比較的に怠け者)があるならば、私はすべて仲介機関を探しに行かなければなりませんか?1種類のものを探して1回で十分ですか??
次のLogTalkを見てください.
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* @author HuYong Email:[email protected] 
*/ 
public class LogTalk implements InvocationHandler { 
private Logger logger = Logger.getLogger(this.getClass().getName()); 

private Object object; 

public Object bind(Object object) { 
this.object = object; 
return Proxy.newProxyInstance(object.getClass().getClassLoader(), 
object.getClass().getInterfaces(), this); 

} 

public Object invoke(Object proxy, Method method, Object[] args) 
throws Throwable { 
Object result = null; 
try { 
log("method starts ...." + method); 
result = method.invoke(object, args); 
log("method ends...." + method); 
} catch (Exception e) { 
log(e.toString()); 
} 
return result; 
} 

private void log(String message) { 
logger.log(Level.INFO, message); 
} 

} 

私がしなければならないことが一つのこと(理解できるもの)であれば、私はまず仲介機関と活動にサインすることができます.私はこれからすべてのあなたが私を手伝ってくれればいいです.私は構造だけでokになります.仲介機関も約束します.あなたが私たちにくれたものがこの約束に合っている限り(すべてObject)、私は受け取ります.
次のようにテストします.
public class TestDynamicProxy{ 
public static void main(String []args){ 
LogTalk dynamicproxy=new LogTalk(); 
ITalk proxy=(ITalk)dynamicproxy.bind(new TalkToSomebody()); 
proxy.talk("YangYi"); 
} 
} 

通过することができて、、、后でこれらの事はあなたはすべて私にすることができて、私はリストを并べて仲介机関にどんな事があって、これらの事はあなたは私にして、もしいつ用事があってする必要がないならば、私はあなたに电话してそれをキャンセルして、他の事の継続に影响しないで、関连する约束を変える必要はありません.
LogTalkについての説明:
public static Object newProxyInstance(ClassLoader loader, 
Class<?>[] interfaces, 
InvocationHandler h) 
throws IllegalArgumentException 
は、指定された呼び出しハンドラにメソッド呼び出しを割り当てることができる指定されたインタフェースのプロキシクラスインスタンスを返す.
public Object bind(Object object) { 
this.object = object; 
return Proxy.newProxyInstance(object.getClass().getClassLoader(), 
object.getClass().getInterfaces(), this); 

バインドは、Objectのサブクラスであればバインドできます(ほほほ、すべてObjectのサブクラスラーです!)
まとめ:これは実はAOPの最下層の実現で、AOPのメリットはエージェントを使って、各種の業務ロジックを分離しました.コアが処理するか、補助機能(またはテスト)としてのビジネスロジック、例えばログがスライスとして各メソッドが実行されているかどうかをテストすることができ、AOPでコアビジネスを変更する必要はありません.不要であれば、Pointcutを指定しないでください.(AOPに関する様々な用語はspring referenceを参照することができる)、これは思想の転換であるべきである.
補足:私が使っている「コアビジネス」は、他の「ビジネスロジック」とは少し異なるかもしれませんが、個人的な理解はこうです.コアビジネスは私が関心を持つ必要があります.これはコアです.他のビジネスロジック(多くの本ではビジネスロジックとは関係のないシステムサービスロジックと呼ばれています)例えば、ログ、セキュリティ面などは、コアのシェルとして、シェルコアがなくても生き残ることができますが、それほど美しくありません.