Reputation: 223
I'm learning AOP and am comfortable with Pointcuts, Advices etc. What am going to ask, am pretty sure is not possible, but want to ask anyways.
I have a method which takes a userId, fetches the user's record from a database and then does something to the record. I have like twenty different methods that do different things, but all of them take the userId as input and fetch the record from database. This to me looks like a cross cutting concern that can be pulled into an aspect.
But how? I know I can access the arguments (userId in this case), access the return value of the method and catch the methods exception. But how do I give the method something to work with (record in the database in this case?)
public String printUserDetails(String userId)
{
Record record = Database.fetchRecord(userId);
System.out.println(record.getDetails());
return record.getTitle();
}
So, is there a way to pull that database accessing code into an aspect?
One way I can think of is declare something like the following for input
class RequestObject
{
String userId;
Record record;
}
and inject the record in the Aspect and then call proceed(). But this somehow feels wrong.
Upvotes: 0
Views: 314
Reputation: 67297
You cannot access a method's local variables from AspectJ if this is what you wanted to know.
The rest of the question is rather about design and the answer dependent on what you want to achieve. You can avoid code duplication in multiple methods using a template method design pattern. You can inject real or mock objects into classes if you refactor them to have a member instead of local variables. It is another question if you create the member by directly refactoring your classes or via AspectJ's (ITD)[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations] mechanism. A third question would be if you possibly want to use an aspect for caching in order to avoid fetching the same object from the database multiple times.
I am not sure what exactly you want to achieve, so I cannot answer more specifically.
Upvotes: 0
Reputation: 24124
IMO, resolving a user, using the userid, is not a cross-cutting concern and hence aspect is not the right way. The first landing page that receives a userId should actually resolve it to UserRecord and from then on, the userRecord should be the one moving around in the application.
A simple analogy I can draw to your scenario from one of my applications is, all authenticated servlets expect the servletRequest.getRemoteUser() to return the valid user login corresponding to the user sending the request. We decorated the HttpServletRequest
to resolve this to a User object in our application and all the authenticated servlets downcast the HttpServletRequest
to AuthenticatedServletRequest
and extract this object. No one else within the application tries to resolve a user login anymore.
Upvotes: 1