How to change attributes of returned object using AspectJ?

I have a class that looks like this (from Spring Roo DataOnDemand), which returns a new transient (non-persistent) object for use in unit testing. This is what the code looks like after we enter from Spring Roo ITD.

public class MyObjectOnDemand { public MyObjectOnDemand getNewTransientObject(int index) { MyObjectOnDemand obj = new MyObjectOnDemand(); return obj; } } 

I need to make additional calls to refer to the returned object in order to set additional fields that the Spring Roo automatically generated method does not care about. Therefore, without changing the above code (or clicking it with Roo ITD), I want to make another call:

 obj.setName("test_name_" + index); 

To do this, I announced a new aspect that has the correct pointcut and which will report the specific method.

 public aspect MyObjectDataOnDemandAdvise { pointcut pointcutGetNewTransientMyObject() : execution(public MyObject MyObjectDataOnDemand.getNewTransientObject(int)); after() returning(MyObject obj) : pointcutGetNewTransientMyObject() { obj.setName("test_name_" + index); } } 

Now, according to Eclipse, pointcut is spelled correctly and advises the correct method. But this does not seem to happen because the integration tests that are stored in the object still do not work, because the name attribute is required but not set. And according to Manning AspectJ in action (section 4.3.2), after consultation, it is assumed that he will be able to change the return values. But maybe I need to do around () advice instead?

+1
source share
3 answers

I would add a comment to tgharold's answer, but did not have a sufficient reputation. (This is my first post)

I know this is old, but I think it can help others who are looking here to know that you can get arguments in advice or advice in AspectJ using thisJoinPoint .

For instance:

 after() : MyPointcut() { Object[] args = thisJoinPoint.getArgs(); ... 

Further information: http://eclipse.org/aspectj/doc/next/progguide/language-thisJoinPoint.html .

Hope this will be helpful to someone.

+3
source

So it turns out that I got an error in Eclipse because it was the wrong weaving of things. Running the “run tests” in the Spring Roo shell made everything work, but running the package as a test case of JUnit did not work.

The above code works using "after return". But you can also implement it with the "around" tip, which allows you to access the arguments passed to the method.

  MyObject around(MyObjectDataOnDemand dod, int index) : pointcutGetNewTransientMyObject() && target(dod) && args(index) { // First, we go ahead and call the normal getNewTransient() method MyObject obj = proceed(dod, index); /* * Then we set additional properties which are required, but which * Spring Roo auto-created DataOnDemand method failed to set. */ obj.setName("name_" + index); // Lastly, we return the object reference return obj; } 

In our particular case, the advice “upon return” was more concise and readable. But it’s also useful to know how to use the “around” tip to access arguments.

0
source

Here's a usage example:

 pointcut methodToMonitor() : execution(@Monitor * *(..)); Object around() : methodToMonitor() { Object result=proceed(); return result; } 
0
source

Source: https://habr.com/ru/post/1445166/


All Articles