@Lookup reference documentation
Issue: SPR-14765
(cherry picked from commit 684d6ab
)
This commit is contained in:
parent
c98cdd4f4c
commit
642fbfba9f
|
@ -2103,7 +2103,6 @@ overrides the method.
|
||||||
in particular not with `@Bean` methods in configuration classes, since the container
|
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
|
is not in charge of creating the instance in that case and therefore cannot create
|
||||||
a runtime-generated subclass on the fly.
|
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
|
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"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
<!-- a stateful bean deployed as a prototype (non-singleton) -->
|
<!-- a stateful bean deployed as a prototype (non-singleton) -->
|
||||||
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
|
<bean id="myCommand" class="fiona.apple.AsyncCommand" scope="prototype">
|
||||||
<!-- inject dependencies here as required -->
|
<!-- inject dependencies here as required -->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- commandProcessor uses statefulCommandHelper -->
|
<!-- commandProcessor uses statefulCommandHelper -->
|
||||||
<bean id="commandManager" class="fiona.apple.CommandManager">
|
<bean id="commandManager" class="fiona.apple.CommandManager">
|
||||||
<lookup-method name="createCommand" bean="command"/>
|
<lookup-method name="createCommand" bean="myCommand"/>
|
||||||
</bean>
|
</bean>
|
||||||
----
|
----
|
||||||
|
|
||||||
The bean identified as __commandManager__ calls its own method `createCommand()`
|
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
|
whenever it needs a new instance of the __myCommand__ bean. You must be careful to deploy
|
||||||
the `command` bean as a prototype, if that is actually what is needed. If it is deployed
|
the `myCommand` bean as a prototype, if that is actually what is needed. If it is
|
||||||
as a <<beans-factory-scopes-singleton,singleton>>, the same instance of the `command`
|
as a <<beans-factory-scopes-singleton,singleton>>, the same instance of the `myCommand`
|
||||||
bean is returned each time.
|
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]
|
[TIP]
|
||||||
====
|
====
|
||||||
|
Another way of accessing differently scoped target beans is an `ObjectFactory`/
|
||||||
|
`Provider` injection point. Check out <<beans-factory-scopes-other-injection>>.
|
||||||
|
|
||||||
The interested reader may also find the `ServiceLocatorFactoryBean` (in the
|
The interested reader may also find the `ServiceLocatorFactoryBean` (in the
|
||||||
`org.springframework.beans.factory.config` package) to be of use. The approach used in
|
`org.springframework.beans.factory.config` package) to be of use.
|
||||||
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.
|
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
|
@ -6625,10 +6666,9 @@ type of configuration provides a natural means for implementing this pattern.
|
||||||
public Object process(Object commandState) {
|
public Object process(Object commandState) {
|
||||||
// grab a new instance of the appropriate Command interface
|
// grab a new instance of the appropriate Command interface
|
||||||
Command command = createCommand();
|
Command command = createCommand();
|
||||||
|
|
||||||
// set the state on the (hopefully brand new) Command instance
|
// set the state on the (hopefully brand new) Command instance
|
||||||
command.setState(commandState);
|
command.setState(commandState);
|
||||||
return command.execute();
|
return command.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// okay... but where is the implementation of this method?
|
// okay... but where is the implementation of this method?
|
||||||
|
|
Loading…
Reference in New Issue