diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Lookup.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Lookup.java index 6b76d23472..64c4f990ac 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Lookup.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Lookup.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,12 +38,15 @@ import java.lang.annotation.Target; * container to fill them in at runtime. In both cases, the container will generate * runtime subclasses of the method's containing class via CGLIB, which is why such * lookup methods can only work on beans that the container instantiates through - * regular constructors (i.e. lookup methods cannot get replaced on beans returned - * from factory methods where we can't dynamically provide a subclass for them). + * regular constructors: i.e. lookup methods cannot get replaced on beans returned + * from factory methods where we cannot dynamically provide a subclass for them. * - *
Note: When used with component scanning or any other mechanism that filters - * out abstract beans, provide stub implementations of your lookup methods to be - * able to declare them as concrete classes. + *
Concrete limitations in typical Spring configuration scenarios:
+ * When used with component scanning or any other mechanism that filters out abstract
+ * beans, provide stub implementations of your lookup methods to be able to declare
+ * them as concrete classes. And please remember that lookup methods won't work on
+ * beans returned from {@code @Bean} methods in configuration classes; you'll have
+ * to resort to {@code @Inject Provider<TargetBean>} or the like instead.
*
* @author Juergen Hoeller
* @since 4.1
diff --git a/src/asciidoc/index.adoc b/src/asciidoc/index.adoc
index 55f1e07423..00a0e2f52f 100644
--- a/src/asciidoc/index.adoc
+++ b/src/asciidoc/index.adoc
@@ -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 `