使用面向方面的编程为方法提供数据

时间:2012-09-21 09:02:01

标签: java aspectj spring-aop aop

我正在学习AOP并且对Pointcuts,Advices等感到满意。 我要问的是,我很确定是不可能的,但无论如何都要问。

我有一个方法,它接受userId,从数据库中获取用户的记录,然后对记录执行某些操作。我有20种不同的方法可以做不同的事情,但是所有这些方法都将userId作为输入并从数据库中获取记录。对我来说,这看起来像是一个可以被拉入一个方面的交叉问题。

但是怎么样?我知道我可以访问参数(本例中为userId),访问方法的返回值并捕获方法异常。但是我如何给方法使用某些东西(在这种情况下记录在数据库中?)

public String printUserDetails(String userId)
{
    Record record = Database.fetchRecord(userId);
    System.out.println(record.getDetails());
    return record.getTitle();
}

那么,有没有办法将数据库访问代码转移到某个方面?

我能想到的一种方法是为输入

声明如下内容
class RequestObject
{
    String userId;
    Record record;
}

并在Aspect中注入记录,然后调用proceed()。但这在某种程度上感觉不对。

2 个答案:

答案 0 :(得分:1)

IMO使用用户ID解析用户并不是一个跨领域的问题,因此方面不是正确的方法。接收userId的第一个登录页面实际上应该将其解析为UserRecord,从那时起,userRecord应该是在应用程序中移动的那个。

我可以从我的一个应用程序中抽取一个简单的类比,所有经过身份验证的servlet都希望servletRequest.getRemoteUser()返回与发送请求的用户相对应的有效用户登录名。我们将HttpServletRequest修改为将其解析为应用程序中的User对象,并将所有经过身份验证的servlet向下转换为HttpServletRequestAuthenticatedServletRequest并提取此对象。应用程序中没有其他人尝试再解析用户登录。

答案 1 :(得分:0)

如果您想知道这一点,则无法从AspectJ访问方法的局部变量。

问题的其余部分是设计,答案取决于你想要达到的目标。您可以使用template method设计模式避免多种方法中的代码重复。如果重构它们以使其具有成员而不是局部变量,则可以将实际或模拟对象注入到类中。如果您通过直接重构您的类或通过AspectJ(ITD)来创建成员是另一个问题[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations机制。第三个问题是,如果您可能希望使用方面进行缓存,以避免多次从数据库中提取相同的对象。

我不确定你想要达到的目标,所以我不能更具体地回答。