问题:FactoryBean实现类和@Bean注解区别,
用户都会显示new 对象。
但是@Bean注释的方法,在生产实例时,会经历初始化前、初始化后整个Spring生命周期。
然而,FactoryBean生产实例,仅执行初始化后过程(用于AOP动作)
问题:依赖原型bean的单例bean
对于单例Bean:Spring容器实例化单例bean并解析注入其依赖项时,该注入只发生一次。
如果您需要在运行时多次使用原型bean的新实例。即:假设单例的bean A在方法调用中使用了非单例的bean B。容器只会创建bean A一次,而只有一个机会来配置属性。 那么容器就无法为每一次创建bean A时都提供新的bean B实例。
1:使用@Lookup注解。
2:使用查找方法注入。
3.放弃IOC,实现ApplicationContextAware接口,引入ApplicationContext,在调用时获取原型实例。
实现示例
package fiona.apple;
// Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class CommandManager implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Object process(Map commandState) {
// grab a new instance of the appropriate Command
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
protected Command createCommand() {
// notice the Spring API dependency!
return this.applicationContext.getBean("command", Command.class);
}
public void setApplicationContext(
ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
package fiona.apple;
// no more Spring imports!
public abstract class CommandManager {
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();
}
// okay... but where is the implementation of this method?
protected abstract Command createCommand();
}
配置xml
<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="myCommand" class="fiona.apple.AsyncCommand" scope="prototype">
<!-- inject dependencies here as required -->
</bean>
<!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="myCommand"/>
</bean>
Spring容器动态地覆盖createCommand()方法的实现。
如果方法是abstract的, 那么动态生成的子类会实现该方法。否则,动态生成的子类将覆盖原始类定义的具体方法
public abstract class CommandManager {
public Object process(Object commandState) {
MyCommand command = createCommand();
command.setState(commandState);
return command.execute();
}
@Lookup
protected abstract MyCommand createCommand();
}