0

在一个简单的 RMI 程序中,我设法在两个线程之间传递上下文。现在我需要将设置/报告从 Context 移动到 AspectJ 类。

我的问题是:如果我需要将上下文用作问候语(上下文)中的参数,如何移动它

你好IF

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";
    }
}

RMI服务器

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.");
    }
}

RMI客户端

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 和 RMIClient Context() 构造函数和 c/context.report()s 转移到 ReportingAspect?

4

1 回答 1

1

您可以将参数传递给函数,并将底层对象传递给 Advice,因此:

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

研究 AspectJ 注释文档以获取完整的详细信息。它可以用于所有的建议类型。

编辑更详细地阅读问题,听起来好像您想让 Context 对象由方面构造和控制,同时仍将其作为参数传递给 Hello.greeting()。

这不是什么有意义的事情。您的底层系统应该可以在没有任何 AOP 的情况下正常工作。因此,如果 Context 对象是该底层域的一部分,那么由 Aspect 负责其构建和管理就不是一个好主意。

如果 Context与 Aspect 相关,那么您将从域类中删除对上下文的所有引用(因此greeting()不带参数)并在 Aspect 中构建 Context 对象。

于 2012-07-31T14:06:15.247 回答