如何将方法移动到AspectJ类?

时间:2012-07-31 13:51:22

标签: java rmi aspectj

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

我的问题是:如果我需要将它用作问候(Context)中的参数

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

1 个答案:

答案 0 :(得分: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()将不带参数)并构建Context对象(s)在方面。