Stronger warning about lookup methods not working with @Bean

Includes an updated CGLIB AOP proxy note on constructor invocations.

Issue: SPR-13108
Issue: SPR-13103
This commit is contained in:
Juergen Hoeller
2015-06-11 18:00:12 +02:00
parent 6f7ad3b1c0
commit 2109db0c02
2 changed files with 24 additions and 22 deletions

View File

@@ -3327,15 +3327,17 @@ overrides the method.
[NOTE]
====
For this dynamic subclassing to work, the class that the Spring container will subclass
cannot be `final`, and the method to be overridden cannot be `final` either. Also,
testing a class that has an `abstract` method requires you to subclass the class
yourself and to supply a stub implementation of the `abstract` method. Finally, objects
that have been the target of method injection cannot be serialized. As of Spring 3.2 it
is no longer necessary to add CGLIB to your classpath, because CGLIB classes are
repackaged under org.springframework and distributed within the spring-core JAR. This is
done both for convenience as well as to avoid potential conflicts with other projects
that use differing versions of CGLIB.
* For this dynamic subclassing to work, the class that the Spring bean container will
subclass cannot be `final`, and the method to be overridden cannot be `final` either.
* Unit-testing a class that has an `abstract` method requires you to subclass the class
yourself and to supply a stub implementation of the `abstract` method.
* Concrete methods are also necessary for component scanning which requires concrete
classes to pick up.
* A further key limitation is that lookup methods won't work with factory methods and
in particular not with `@Bean` methods in configuration classes, since the container
is not in charge of creating the instance in that case and therefore cannot create
a runtime-generated subclass on the fly.
* Finally, objects that have been the target of method injection cannot be serialized.
====
Looking at the `CommandManager` class in the previous code snippet, you see that the
@@ -15610,13 +15612,10 @@ so. However, there are some issues to consider:
CGLIB classes are repackaged under org.springframework and included directly in the
spring-core JAR. This means that CGLIB-based proxy support 'just works' in the same
way that JDK dynamic proxies always have.
* The constructor of your proxied object will be called twice. This is a natural
consequence of the CGLIB proxy model whereby a subclass is generated for each proxied
object. For each proxied instance, two objects are created: the actual proxied object
and an instance of the subclass that implements the advice. This behavior is not
exhibited when using JDK proxies. Usually, calling the constructor of the proxied type
twice, is not an issue, as there are usually only assignments taking place and no real
logic is implemented in the constructor.
* As of Spring 4.0, the constructor of your proxied object will NOT be called twice
anymore since the CGLIB proxy instance will be created via Objenesis. Only if your
JVM does not allow for constructor bypassing, you might see double invocations and
corresponding debug log entries from Spring's AOP support.
To force the use of CGLIB proxies set the value of the `proxy-target-class` attribute of
the `<aop:config>` element to true: