当你在spring @Component中使用@Autowired时,spring会为组件的每个实例化确定autowire候选者,当你使用@Request / @ Session scoped web东西时,这真的不太好。为什么Spring只在ApplicationContext中创建一个bean定义并重新使用它?有没有办法让它这样做?
答案 0 :(得分:1)
是的:当您将范围设置为其他内容时,Spring将重用该组件(即您不得使用原型,会话或请求)。所以诀窍是使用两个 bean:其中包含所有不会改变的东西。并且一个bean附加到会话/请求并且只有一个依赖:第一个bean。
Spring不能为你做这个,因为当bean足够“静态”时没有规则 - 你作为开发者必须确定它。
[编辑] 您必须在DAO /服务bean中收集bean的静态部分(那些不会随时间变化的部分)。然后在@Component
- >中使用该bean一次查询。
要加快查找速度,请将名称附加到组件。对于基于类型的查找,Spring必须迭代整个上下文(因为几个bean可以匹配),而基于名称/ ID的查找只是在地图中查找。
要为bean指定名称,请在@Context
中指定,或使用@Bean(name="name")
。要告诉Spring在上下文中使用哪个bean,请使用@Resource(name)
或@Qualifier("businessObject")
。
答案 1 :(得分:1)
AutowiredAnnotationBeanPostProcessor
是BeanPostProcessor
,而不是BeanFactoryPostProcessor
,因此无法按设计编辑Bean定义。以不同方式实现会破坏预期的功能:
public class MyBean{
@Autowired(required=false)
public void setOtherBean(OtherBean o){this.otherBean=o;}
private OtherBean otherBean;
}
如果没有OtherBean
实例可用,则不会连接任何实例,但只要一个可用(并且我可以轻松地以编程方式连接一个),下一个MyBean
实例(如果范围不是单例) )将获得新的OtherBean
(以前不可用)。
我不是说这是我之前遇到的一个用例,但它是一个有效的用例,如果事情按照你建议的方式运行会破坏它。
答案 2 :(得分:0)
最佳做法是使用服务类,组件,DAO等作为单例,并在应用程序上下文中只有一个实例。@ Component注释只会在组件扫描过程中找到实例,这意味着它们是在春天的背景下自动扫描和生活实例的候选人。 例如:
@Component
public class StudentDAO {
@Override
public String toString() {
return " inside StudentDAO";
}
}
StudentDAO是一个数据访问对象,在最佳实践中,上下文中不需要此服务calss的多个实例。它基本上是一个服务类。它是单身人士的完美候选人。如果只有这个对象的一个实例,自动装配也可以有效地工作8-)。但是你必须要小心对单例方法的访问,并决定将你的方法标记为同步以防止线程的不受欢迎的影响。
答案 3 :(得分:0)
手动替代方法是在bean中注入单例范围的Provider
,它提供原型范围的bean。
这意味着程序员可以完成更多的工作,但是性能损失将被消除。
答案 4 :(得分:0)
在请求/会话范围的bean上设置@Scope批注的proxyMode属性。 Spring将创建一个自动连接的代理 - 代理将查找在其上调用方法的实际bean。