按类型@Autowired可以生成bean定义吗?

时间:2011-03-22 09:56:35

标签: java spring autowired

当你在spring @Component中使用@Autowired时,spring会为组件的每个实例化确定autowire候选者,当你使用@Request / @ Session scoped web东西时,这真的不太好。为什么Spring只在ApplicationContext中创建一个bean定义并重新使用它?有没有办法让它这样做?

5 个答案:

答案 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)

AutowiredAnnotationBeanPostProcessorBeanPostProcessor,而不是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。