2

当您在 spring @Component 中使用 @Autowired 时,spring 会为组件的每个实例化确定自动装配候选者,这在您使用 @Request/@Session 范围的 Web 内容时确实不好。为什么 spring 不只在 ApplicationContext 中定义一个 bean 并重新使用它?有没有办法让它这样做?

4

5 回答 5

1

是的:当您将范围设置为其他内容时,Spring 将重用该组件(即您不得使用原型、会话或请求)。所以诀窍是使用两个bean:一个包含所有不变的东西。还有一个 bean 附加到会话/请求并且只有一个依赖项:第一个 bean。

Spring 不能为您执行此操作,因为当 bean 足够“静态”时没有规则——您作为开发人员必须确定这一点。

[编辑]您必须在 DAO/服务 bean 中收集 bean 的静态部分(那些不会随时间变化的部分)。@Component然后在您的-> 一个查找中使用该 bean 。

要加快查找速度,请将名称附加到组件。对于基于类型的查找,Spring 必须遍历整个上下文(因为可以匹配多个 bean),而基于名称/ID 的查找只是在映射中查找。

要为 bean 命名,请在 中指定它@Context,或使用@Bean(name="name")。要告诉 Spring 从上下文中使用哪个 bean,请使用@Resource(name)or @Qualifier("businessObject")

于 2011-03-22T10:01:20.400 回答
1

AutowiredAnnotationBeanPostProcessor是 a BeanPostProcessor,而不是 a BeanFactoryPostProcessor,因此它无法根据设计编辑 Bean 定义。以不同的方式实现会破坏预期的功能:

public class MyBean{

    @Autowired(required=false)
    public void setOtherBean(OtherBean o){this.otherBean=o;}
    private OtherBean otherBean;

}

如果没有OtherBean可用的实例,则不会连接任何实例,但是一旦一个可用(我可以轻松地以编程方式连接一个),下一个MyBean实例(如果范围不是单例)将获得新的实例(OtherBean以前不可用)。

我并不是说这是我以前遇到过的用例,但它是一个有效的用例,如果事情按照您建议的方式工作,它就会中断。

于 2011-03-22T13:46:30.953 回答
0

最佳实践是使用服务类、组件、DAO 等作为单例,并在应用程序上下文中只有一个实例。@Component 注释导致仅在组件扫描过程中找到实例,这意味着它们是 auto 的候选者-在春季环境中扫描和生活实例。例如:

@Component
public class StudentDAO {
        @Override
        public String toString() {
                return " inside StudentDAO";
        }
}

StudentDAO 是一个数据访问对象,在最佳实践中,在上下文中不需要此服务类的多个实例。它基本上是一个服务类。它是单身人士的完美候选人。如果周围只有这个对象的一个​​实例,那么自动装配也可以有效地工作 8-)。但是您仍然必须注意对单例方法的访问,并决定将您的方法标记为同步以防止线程的意外影响。

于 2011-03-22T10:18:56.143 回答
0

手动替代方法是将单例范围Provider注入到提供原型范围 bean 的 bean 中。

这意味着程序员需要完成更多的工作,但仍然会消除对性能的影响。

于 2011-03-22T14:03:03.997 回答
0

在请求/会话范围的 bean 上设置 @Scope 注释的 proxyMode 属性。Spring 将创建一个将自动连接的代理 - 代理将查找在其上调用方法的实际 bean。

于 2011-03-23T09:22:30.740 回答