diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index 2f1cf5c117..16f88f2ccc 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -2103,7 +2103,6 @@ overrides the method. 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 @@ -2150,30 +2149,72 @@ the original class. For example: [subs="verbatim,quotes"] ---- - + - + ---- The bean identified as __commandManager__ calls its own method `createCommand()` -whenever it needs a new instance of the __command__ bean. You must be careful to deploy -the `command` bean as a prototype, if that is actually what is needed. If it is deployed -as a <>, the same instance of the `command` +whenever it needs a new instance of the __myCommand__ bean. You must be careful to deploy +the `myCommand` bean as a prototype, if that is actually what is needed. If it is + as a <>, the same instance of the `myCommand` bean is returned each time. +Alternatively, within the annotation-based component model, you may declare a lookup +method through the `@Lookup` annotation: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + public abstract class CommandManager { + + public Object process(Object commandState) { + Command command = createCommand(); + command.setState(commandState); + return command.execute(); + } + + @Lookup("myCommand") + protected abstract Command createCommand(); + } +---- + +Or, more idiomatically, you may rely on the target bean getting resolved against the +declared return type of the lookup method: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + public abstract class CommandManager { + + public Object process(Object commandState) { + MyCommand command = createCommand(); + command.setState(commandState); + return command.execute(); + } + + @Lookup + protected abstract MyCommand createCommand(); + } +---- + +Note that you will typically declare such annotated lookup methods with a concrete +stub implementation, in order for them to be compatible with Spring's component +scanning rules where abstract classes get ignored by default. This limitation does not +apply in case of explicitly registered or explicitly imported bean classes. + [TIP] ==== +Another way of accessing differently scoped target beans is an `ObjectFactory`/ +`Provider` injection point. Check out <>. + The interested reader may also find the `ServiceLocatorFactoryBean` (in the -`org.springframework.beans.factory.config` package) to be of use. The approach used in -ServiceLocatorFactoryBean is similar to that of another utility class, -`ObjectFactoryCreatingFactoryBean`, but it allows you to specify your own lookup -interface as opposed to a Spring-specific lookup interface. Consult the javadocs of -these classes for additional information. +`org.springframework.beans.factory.config` package) to be of use. ==== @@ -6625,10 +6666,9 @@ type of configuration provides a natural means for implementing this pattern. public Object process(Object commandState) { // grab a new instance of the appropriate Command interface Command command = createCommand(); - // set the state on the (hopefully brand new) Command instance command.setState(commandState); - return command.execute(); + return command.execute(); } // okay... but where is the implementation of this method?