Java 如何避免在春季使用applicationContext.getBean?
我有一个类条实现如下:Java 如何避免在春季使用applicationContext.getBean?,java,spring,dependency-injection,Java,Spring,Dependency Injection,我有一个类条实现如下: class Bar implements ApplicationContextAware { ApplicationContext applicationContext; void barFoo() { final Foo foo = applicationContext.getBean(Foo.class); foo.doSomeWork(); foo.shutDownProperly(); }
class Bar implements ApplicationContextAware {
ApplicationContext applicationContext;
void barFoo() {
final Foo foo = applicationContext.getBean(Foo.class);
foo.doSomeWork();
foo.shutDownProperly();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>
而foo在我的配置中定义如下:
class Bar implements ApplicationContextAware {
ApplicationContext applicationContext;
void barFoo() {
final Foo foo = applicationContext.getBean(Foo.class);
foo.doSomeWork();
foo.shutDownProperly();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>
因为,Singleton Foo无法正确完成工作,每次都必须正确关闭
我认为getBean
打破了整个“依赖注入”/“可测试”原则
但是对于“barFoo”方法,我如何将“原型Foo”注入“Bar”中?您可以使用org.springframework.beans.factory.ObjectFactory:
class Bar {
@Autowired
private ObjectFactory<Foo> fooObjectFactory;
}
您可以使用org.springframework.beans.factory.ObjectFactory:
class Bar {
@Autowired
private ObjectFactory<Foo> fooObjectFactory;
}
所以您需要在单例bean中注入原型bean,并在单例方法的每次调用中使用原型bean的新版本 您可以尝试使用ScopedProxyFactoryBean,但是Spring框架参考手册建议使用查找方法注入 您的
Bar
课程将成为:
class Bar implements ApplicationContextAware {
ApplicationContext applicationContext;
void barFoo() {
final Foo foo = createFoo();
foo.doSomeWork();
foo.shutDownProperly();
}
protected abstract Foo createFoo(); // Implementation will be provided by Spring Framework
}
您只需在bean定义中声明方法:
<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>
<bean id="bar" class="biz.tugay.Bar">
<lookup-method name="createFoo" bean="command"/>
</bean>
参考文献(重点):
具有原型bean依赖项的单例bean..
但是,假设您希望单例作用域bean获取原型作用域的新实例 bean在运行时重复运行。您不能将依赖项注入原型范围的bean singleton bean,因为当Spring容器实例化 SingletonBean及其依赖项的解析和注入如果您需要原型的新实例 bean多次运行,请参阅名为“方法注入”的部分 及 查找方法注入 查找方法注入是容器重写容器管理bean上的方法的能力, 返回容器中另一个命名bean的查找结果。查找通常涉及 原型bean[…]。Spring框架实现了 该方法通过使用CGLIB库中的字节码生成来动态生成 重写该方法的子类
所以您需要在单例bean中注入原型bean,并在单例方法的每次调用中使用原型bean的新版本 您可以尝试使用ScopedProxyFactoryBean,但是Spring框架参考手册建议使用查找方法注入 您的
Bar
课程将成为:
class Bar implements ApplicationContextAware {
ApplicationContext applicationContext;
void barFoo() {
final Foo foo = createFoo();
foo.doSomeWork();
foo.shutDownProperly();
}
protected abstract Foo createFoo(); // Implementation will be provided by Spring Framework
}
您只需在bean定义中声明方法:
<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>
<bean id="bar" class="biz.tugay.Bar">
<lookup-method name="createFoo" bean="command"/>
</bean>
参考文献(重点):
具有原型bean依赖项的单例bean..
但是,假设您希望单例作用域bean获取原型作用域的新实例 bean在运行时重复运行。您不能将依赖项注入原型范围的bean singleton bean,因为当Spring容器实例化 SingletonBean及其依赖项的解析和注入如果您需要原型的新实例 bean多次运行,请参阅名为“方法注入”的部分 及 查找方法注入 查找方法注入是容器重写容器管理bean上的方法的能力, 返回容器中另一个命名bean的查找结果。查找通常涉及 原型bean[…]。Spring框架实现了 该方法通过使用CGLIB库中的字节码生成来动态生成 重写该方法的子类
取决于上下文,但您可能希望使用原型bean而不是singleton@NickVanderhovenFoo已经是原型了,但是Bar本身是单例的。这取决于上下文,但是您可能希望使用原型bean而不是singleton@NickVanderhovenFoo已经是原型了,但Bar本身是单例的。ObjectFactory的所有实现似乎都是私有内部类,而Autowired似乎不起作用。ObjectFactory的所有实现似乎都是私有内部类,而Autowired似乎不起作用。