0

単純なRMIプログラムで、2つのスレッド間でコンテキストを渡すことができました。次に、設定/レポートをContextクラスからAspectJクラスに移動する必要があります。

私の問題は次のとおりです。greeting(Context)の引数として使用する必要がある場合にコンテキストを移動する方法

HelloIF

public interface HelloIF extends Remote {
    String greeting(Context c) throws RemoteException;
}

こんにちは

public class Hello extends UnicastRemoteObject implements HelloIF {

    public Hello() throws RemoteException {
    }

    public String greeting(Context c) throws RemoteException {
        c.report();
        return "greeting";
    }
}

RMIServer

public class RMIServer {

    public static void main(String[] args) throws RemoteException, MalformedURLException {
        LocateRegistry.createRegistry(1099);
        HelloIF hello = new Hello();
        Naming.rebind("server.Hello", hello);
        System.out.println("server.RMI Server is ready.");
    }
}

RMIClient

public class RMIClient {
    public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException {

        Context context = new Context("request1", Thread.currentThread().getName()+System.currentTimeMillis());

        Registry registry = LocateRegistry.getRegistry("localhost");
        HelloIF hello = (HelloIF) registry.lookup("server.Hello");
        System.out.println(hello.greeting(context));

        context.report();

    }
}

コンテクスト

public class Context implements Serializable
{
    private String requestType;
    private String distributedThreadName;

    public Context(String requestType, String distributedThreadName)
    {
        this.requestType = requestType;
        this.distributedThreadName = distributedThreadName;
    }

    (...)

    public void report() {
        System.out.println("thread : "
                + Thread.currentThread().getName() + " "
                + Thread.currentThread().getId());

        System.out.println("context : "
                + this.getDistributedThreadName() + " " + this.getRequestType());
    }
}

そして最後に空のAspectJクラス

@Aspect
public class ReportingAspect {
    @Before("call(void main(..))")
    public void beforeReportClient(JoinPoint joinPoint) throws Throwable {
    }

    @After("call(void main(..))")
    public void afterReportClient(JoinPoint joinPoint) throws Throwable {
    }

    @Before("call(String greeting(..))")
    public void beforeReportGreeting(JoinPoint joinPoint) throws Throwable {
    }

    @After("call(String greeting(..))")
    public void afterReportGreeting(JoinPoint joinPoint) throws Throwable {
    }

}

HelloおよびRMIClientContext()コンストラクターとc / context.report()sからReportingAspectに移動するにはどうすればよいですか?

4

1 に答える 1

1

引数を関数に渡し、基になるオブジェクトをアドバイスに渡すことができます。したがって、次のようになります。

@Before("execution(* greeting(..)) && target(target) && " +
        "args(context)")
public void beforeReportGreeting(HelloIF target, Context context) {
       context.doSomething();
       target.doSomething();
}

詳細については、AspectJアノテーションのドキュメントをご覧ください。これは、すべてのアドバイスタイプに対して実行できます。

編集質問をより詳細に読むと、Hello.greeting()に引数として渡しながら、Contextオブジェクトをアスペクトによって構築および制御されるものにしたいように聞こえます。

それは理にかなっていることではありません。基盤となるシステムは、AOPが実行されていなくても正常に機能するはずです。したがって、Contextオブジェクトがその基礎となるドメインの一部である場合、アスペクトがその構築と管理を担当することはお勧めできません。

コンテキストがアスペクトにのみ関連する場合は、ドメインクラスからコンテキストへのすべての参照を削除し(したがってgreeting()、パラメーターを取りません)、アスペクトでコンテキストオブジェクトを構築します。

于 2012-07-31T14:06:15.247 に答える