Spring ApplicationContext.getBean(Class c) not working for proxy classes - java

I need to look up beans via their class type. When the beans have been wrapped by a Proxy (some methods are #Transactional) - the ApplicatoinContext fails to find them. I find that if I look them up via an interface, it works but in this case I'm working with a concrete class type. I know the bean is of the type I'm looking for but the getBean() method fails.
I can debug (and fix) the problem in Spring's AbstractBeanFactory code. The issue is that it checks the type of the beanInstance against type I'm requesting but the beanInstance.getClass() is a Proxy. AbstractBeanFactory should compensate for this and compare the type to the proxy's target class.
I have a fix for this but I don't particularly want to use a patched version of Spring and I suspect there must be something I can configure to get this working, or is this really a bug?

There are two major ways Spring implements AOP (e.g. #Transactional support): either by using proxy interfaces or CGLIB.
With interfaces (default) if your class implements any interfaces, Spring will create a proxy implementing all that interfaces. From now on you can only work with your bean through that interfaces. Your class is deeply burried inside them.
If you enable proxying target classes instead via cglib:
<aop:config proxy-target-class="true">
Spring will create a subclass (obvoiusly still implementing all your interfaces) instead. This will fix your problem. However remember that the returned object is not really your class but dynamically generated subclass that wraps and delegates to your original object. This shouldn't be a problem in most of the cases.
And no, of course this is not a bug but well known behaviour and no, there is no need to patch Spring.
See also
Location of the proxy class generated by Spring AOP
Getting Spring Error "Bean named 'x' must be of type [y], but was actually of type [$Proxy]" in Jenkins
How to mix CGLIB and JDK proxies in Spring configuration files?
Mocking a property of a CGLIB proxied service not working

<context:component-scan base-package="<Your base package name goes here>" />
<aop:aspectj-autoproxy />
<aop:config proxy-target-class="true"/>
write these three lines in applicationContext.xml this worked for me.

Related

Confusing *CGLIB class names when Dynamic Proxy should be used in Spring Boot/MVC

As far as I know whenever I use interfaces for my beans, JDK Dynamic Proxies should be used instead of CGLIB. To be on teh safe side, I make sure I don't even have CGLIB in the classpath of my Spring Boot app.
However, when my controller implements an interface I see this in the stacktrace(never mind the stacktrace rootcause, it was a validation error):
at com.yuranos.documented.api.controllers.BookingControllerImpl.convertToDto(BookingControllerImpl.java:57)
at com.yuranos.documented.api.controllers.BookingControllerImpl.getBookingById(BookingControllerImpl.java:29)
at com.yuranos.documented.api.controllers.BookingControllerImpl$$FastClassBySpringCGLIB$$890fcd8a.invoke(<generated>)
What is even more confusing is that when I remove the interface, this strangely named proxy disappears:
at com.yuranos.documented.api.controllers.BookingControllerImpl.convertToDto(BookingControllerImpl.java:60)
at com.yuranos.documented.api.controllers.BookingControllerImpl.getBookingById(BookingControllerImpl.java:32)

Spring change cglib

I am use Spring in my app, when we have some class that doesn't implements any interface, Spring will use "cglib" to proxy.
Can I change the cglib to other lib in Spring? If yes, How can I do it?
Thanks!
[EDIT]
Hi, I was wanting because I have problems with PermGen when I use CGLIB, the proxys instance are not cleaning when I do hotdeploy.
Yes, I can change for other stretegy, Aspect etc...
Spring only supports JDK (interface only) and CGLIB based (for classes) proxying, and while it's not explicitly mentioned, it also uses Objenesis with CGLIB for proxying classes with no default constructor. Also see their issues regarding this at https://jira.spring.io/browse/SPR-8190 and https://jira.spring.io/browse/SPR-5654 for further reference. That means there's no drop-in replacement or configuration options in Spring to switch to some other proxy creation method.
If you're still willing to explore uncharted territories, the DefaultAopProxyFactory might be a good place to start as it seems it's a central piece of the proxy creation code in Spring, the proxy creator classes use it as a factory through their common superclass ProxyCreatorSupport.

Spring aop intercepting calls from within the same service class

I have a same scenario as mentioned in
Spring #Transaction method call by the method within the same class, does not work?
I was referring to answer #1 which i thought would work for my simple pojo class but it didnt. In my case i dont have annotation #Transaction. Its a simple pojo class. I wish to intercept each method adduser as well as addusers using spring aop if i take example in post above.
Is it possible to intercept method that is being called from the same service call? I was referring to AspectJAwareProxy which does the trick but doesnt resolve the issue as a whole. What i mean is i dont want anything to be added to my business logic. So i want to avoid any coding except for defining pointcut and defining the advice. Is it something possible using Java and spring aop? I am using CGlib to generate proxy. Spring version is 3.0.5.Release.
Thanks,
Ajay
For this to work, you have to use load-time weaving instead of proxying. The reason is because spring uses proxying to achieve AOP functionality (such as transaction support). Once inside a class instance, any method-calls to methods in the same instance will be directly against the actual instance object, not the wrapping proxy so AOP advices will not be considered. Load-time weaving works differently. There, you have an outside java agent that manipulates the classes on a byte-code level to inject the AOP support.
You will need to
1: Modify your java command-line used to include the spring aspectj agent
2: add
<context:load-time-weaver aspectj-weaving="on" />
<tx:annotation-driven mode="aspectj" />
to your spring cofig.
Read more:
AspectJ Load Time Weaving with Spring Transaction Manager and Maven
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-aj-ltw

What is the meaning of using proxy ( dynamic proxy) in spring framework?

I don't know the meaning of using proxy in spring. what is efficient?
Proxies are used by AOP. In short:
Normally you have.
Caller --> Real object
But when, for example, you want automatic transaction management, spring puts a proxy of your real object
Caller --> Proxy --> Real object
where the proxy starts the transaction.
Here is nice article explaining both the essence of proxies and their efficiency (performance) in spring
The dynamic proxy is a feature of the JDK. It can be used to implement an interface using an invocation handler.
A dynamic proxy class (simply referred
to as a proxy class below) is a class
that implements a list of interfaces
specified at runtime when the class is
created, with behavior as described
below. A proxy interface is such an
interface that is implemented by a
proxy class. A proxy instance is an
instance of a proxy class. Each proxy
instance has an associated invocation
handler object, which implements the
interface InvocationHandler.
A dynamic proxy has some overhead. For most use cases the overhead won't be significant, though. The real problem is that the (over)use of dynamic proxies makes an application harder to understand and debug. For example a dynamic proxy will show up with mulitple lines in a stacktrace.
Dynamic proxies are often used to implement decorators. One example of this is AOP in Spring. (I don't want to go into the details of AOP and won't use AOP terminology to keep things simple). Where certain concerns are implemented in one class and used in many places. The dynamic proxies (and invocation handlers) are only the glue code (provided by Spring) to intercept the method calls. (Actually, dynamic proxies are only an implementation detail of this capability. Generating classes on the fly is another possibility to implement it.)
We can add a functionality to Java class by modifying the source/byte code or by using subclass or proxy which embeds the additional functionality and delegates the calls to underlying object.
The other answers are good, but here's how I think of it in very simple terms.
An annotation means "add hidden code for extra behavior."
The framework (or whatever knows what the annotation means) adds bytecode, Spring at runtime, AspectJ at compile time, for example.
It adds code as a proxy along with an interceptor. (A wrapper, decorator, adapter are similar and may be easier to understand than "proxy".)
When the program runs, the interceptor sends execution to the proxy which does its thing, which then may or may not send execution to the class that you coded and that it "wraps".
AOP can also use CGLIB proxies. This is used to proxy the classes instead of interfaces.

Is fine grained control of aspectj-autoproxy possible in spring?

If I just add <aop:aspectj-autoproxy proxy-target-class="false"/> to the start of my spring context, every single bean that implements an interface gets a JDK proxy. I would really like to limit the proxying A) to classes that actually need proxies or B) classes that I specify as needing proxies.
I tried using the aop:scoped-proxy stanza within an xml bean defintion for the beans that need proxies, but it turns out this does not seem to give me aop-advice.
I also tried adding <aop:aspectj-autoproxy ....> near the end of my spring xml file, but before adding all the beans that need proxies, but it does not seem to work properly.
I have a lot of beans with interfaces but only a (well defined) handful need AoP advice, and those proxies are messing up my stacktraces big time. (I have peeked at spring 3.0 and suspect it's going to be possible there but it seems like it's a while away).
Is this possible in 2.5.X ?
As can be seen in AbstractAdvisorAutoProxyCreator.java line 67 (Spring 2.5.6), the autoproxy creator really only does what I ask it to. It does not autoproxy more than it thinks necessary.
It turns out it's the kind of pointcut expression you use greatly influences how much proxying this class does; the annotation I was using was
#Around(value="#target(myannotation)")
This basically means spring generates a proxy that decides to intercept based on the type of the actual invocation target. The downside of this is that spring tries to do this with all available beans in the applicationcontext. If I'd been using something like#within instead, spring would be using the interface to decide if autoproxying should take place, and this can statically be determined at the time the applicationcontext is built.
So now I only have two classes that are proxied ;)

Categories

Resources