Your code seems to imply that your aspects are working, i.e. before/after advices from your configuration get executed. If they don't, you have problems in other places. I am further assuming that
- your aspects work as designed and you have checked that,
- you are using Spring AOP, not AspectJ with load-time weaving,
- somehow GSON is seeing CGLIB proxies, not the original objects underneath.
Then the problem could be that GSON - I have zero experience with it, never used it before - uses reflection in order to search for fields in the proxy class. But it will not find any as the proxy only overrides methods, but does not have fields because the latter are in the original class (parent to the proxy). If this is true, you need to configure GSON to search in the original class, not in the proxy class. Then you also would not have to exclude anything.
Update:
My educated guess above was correct.
Just because I was curious about how to get the original object from a CGLIB proxy, I looked at it in a debugger. It seems like every proxy has a public final method getTargetSource
which you can invoke via reflection:
package com.tutorial;
import org.springframework.aop.TargetSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Application {
public static void main(String[] args) throws Exception {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
Student student = (Student) context.getBean("student");
TargetSource targetSource = (TargetSource)
student
.getClass()
.getMethod("getTargetSource", null)
.invoke(student, null);
System.out.println(gson.toJson(targetSource.getTarget()));
}
}
This works for me with your code, but I did not use Lombok (which you did not mention at all, I just found out when trying to compile your code!) in the mix but manually created constructors, getters and setters just to get up and running.
Besides, you do not need the ExclusionStrategy
anymore.
Console log:
{
"age": 11,
"name": "Zara"
}
BTW, Lombok is known to cause trouble in connection with AspectJ because of class naming conflicts, see my answer here. This might also affect Spring AOP.
I think that you use an unhealthy (because incompatible) mix of technologies here, if you find a solution and do not want to end up writing custom type adapters for each bean class it will be quite hacky. If you remove Lombok, at least you can switch from Spring AOP to AspectJ with LTW in order to get rid of the proxy problem. AspectJ does not use proxies, so GSON might work better with it.
Update 2:
My first update was just a quick hack during a tea break. Not being a Spring user, I had too look up the API doc first in order to find interface Advised
. It contains method getTargetSource()
, i.e.:
- We can cast our Spring bean (AOP proxy) to
Advised
and thus avoid ugly reflection.
- Going one step further, we can dynamically determine if a given object is an (advised) proxy or not, i.e. if you change or deactivate your aspect, the same code will still work.
package com.tutorial;
import org.springframework.aop.framework.Advised;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Application {
public static void main(String[] args) throws Exception {
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("aop.xml")) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Student student = (Student) context.getBean("student");
System.out.println(gson.toJson(unProxy(student)));
}
}
public static Object unProxy(Object object) throws Exception {
return object instanceof Advised
? ((Advised) object).getTargetSource().getTarget()
: object;
}
}
Update 3: I was curious and also installed Lombok for my IDE. Actually the sample from above does work in connection with Gson and my little unProxy(Object)
method. So you are good to go. :-)