Is it possible to intercept object method call and modify those object properties at that moment?
What I have so far
@Pointcut("execution(* java.net.HttpURLConnection.setRequestProperty(..))")
public void connectMethodCall() {
}
@Around("connectMethodCall()")
public Object onGetUrlConnection(ProceedingJoinPoint pjp) throws Throwable {
HttpURLConnection connection = (HttpURLConnection) pjp.proceed();
connection.setRequestProperty("header key", "header value");
return pjp.proceed();
}
I want to at this example set connection headers and return the object to execution point. Weaving is done at compile time. I try to log headers after this but there are no headers that I have set in @Around advice. No errors are thrown either.
The answer to your follow-up question about how to get hold of an instance of the target object is simple, if I understand the question correctly: Just use the target()
parameter binding. A quick look into the AspectJ documentation would have showed you that, e.g. the part about pointcut parameters. I do believe it is much easier and less time-consuming (also with regard of having to wait for answers on SO) than asking questions here. But anyway, this is a place where developers help each other. So here we go:
Disregarding the fact that your MVCE sample code does not do anything meaningful with the Google API, let's just add one line of diagnostic output in order to verify that the aspect actually did add a request parameter:
// (...)
urlConnection.connect();
// Just in order to check if the property has indeed been set in the aspect
System.out.println(urlConnection.getRequestProperty("From"));
OutputStream outputStream = urlConnection.getOutputStream();
// (...)
Then use this aspect:
package de.scrum_master.aspect;
import java.net.HttpURLConnection;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MyAspect {
@Pointcut("call(* java.net.HttpURLConnection.connect()) && target(connection)")
public void connectMethodCall(HttpURLConnection connection) {}
@Around("connectMethodCall(connection)")
public Object onGetUrlConnection(ProceedingJoinPoint pjp, HttpURLConnection connection) throws Throwable {
connection.setRequestProperty("From", "user@example.com");
return pjp.proceed();
}
}
Or a little bit more compact, if you do not need the poinctut to be re-useable because you only use it in one advice:
@Aspect
public class MyAspect {
@Around("call(* java.net.HttpURLConnection.connect()) && target(connection)")
public Object onGetUrlConnection(ProceedingJoinPoint pjp, HttpURLConnection connection) throws Throwable {
connection.setRequestProperty("From", "user@example.com");
return pjp.proceed();
}
}
The console log would be:
user@example.com
false : 405