2008-10-17 49 views
9

在spring中,可以通过使applicationContext.xml调用构造函数来初始化bean,也可以在bean上设置属性。这两种方法之间的折衷是什么?有一个构造函数(它在一种方法中强制执行它需要的所有内容)或更好地拥有所有属性(这使得您可以灵活地仅在单元测试时选择性地进行注入)更好吗?什么是初始化bean的最佳方式?

什么(在编写一个使用构造函数来建立它的初始状态的bean,或使用属性和可能的​​afterProperties()方法)之间进行权衡?

回答

15

我不确定是否有“最佳”的方式来初始化一个bean。我认为每个人都有优点和缺点,并且根据情况,其中一个或另一个可能是合适的。这当然不是一个详尽的清单,但这里有一些需要考虑的事项。

使用构造函数可以让你拥有一个不可变的bean。如果你可以将它们放在你的设计中,那么不可变的物体是很好的。它们不需要在线程之间进行复制,序列化访问或其他特殊处理。如果你有setter,你的对象是不可改变的。使用构造函数还可确保对象正确初始化。构造函数完成后,该对象是有效的。如果您的对象要求使用setter来初始化它,那么可能会有一个无效的对象。

另一方面,使用构造函数通常会导致伸缩问题。通常情况下,您需要许多不同的构造函数,其中大部分将是另一个构造函数的超集。通常这些都是为了方便。例如:

public class Person { 
    public Person(String name) { ... } 
    public Person(String name, String phone) { ... } 
    public Person(String name, String phone, String email) { ... } 
} 

一种可以替代的,我非常喜欢的就是所谓的“增强型”建设者在JavaOne会议上通过乔希布洛赫呈现模式。你可以在他的书“Effective Java,Second Edition”中看到这一点。如果您查看模式的使用方式,它也将解决您的“afterProperties”方法问题。构建器模式将确保对象正确初始化。

这是一个额外的博客文章讨论的模式:http://www.screaming-penguin.com/node/7598

我不知道这个适合你的春天的要求,但在一般情况下,我是建设者的大风扇。

+0

+1 - 真的很好的答案 – 2009-03-11 02:36:20

3

IMO构造函数注入的主要优点是它兼容不变性。但是,如果一个类有超过3个依赖关系,则需要提供一个构造函数,该构造函数需要大量的参数,这很笨拙。

当使用setter-injection时,我更喜欢使用@PostConstruct注释来标识初始化方法。这涉及到比您提到的afterProperties()方法更松散的耦合到Spring框架(实际上,我认为它是afterPropertiesSet())。另一个选项是<bean>元素的init方法属性。

2

我不知道你当前使用的版本,但如果它是Spring 2.5,你也可以考虑在某些情况下使用@Autowired注解。这种粗糙只适用于其他bean的引用,而不适用于字符串等,如lycony的示例。

它为您节省了创建setter和/或构造函数的负担以及大量的配置。 一个小例子:

public class MyPersonBean { 
    @Autowired 
    private PersonManager personManager; 

    public void doSomething() { 
    this.personManager.doSomething(); 
    } 
} 

而且在你的配置文件:

<context:annotation-config/> 

自动装配由类型来完成的,所以如果你有类型的PersonManager的豆,它会在注释字段注入它。如果你有这种类型的,你可以使用@Qualifier注解告诉他们分开的豆类...

您可以找到有关在​​

自动装配更多的信息,我开始与部件组合使用@Autowired - 在我以前的项目中扫描,我必须说我摆脱了超过90%的Spring配置文件。

0

的权衡:

构造: 优点: 可以很简单,ESP。具有三个或更少的属性来初始化。 一次性,无/极少额外配置担心。

缺点: 多个构造必须几种情况 构造函数是不可继承的创建,因此类必须调用super(),并提供重复的构造,使以前的行为。

安装人: 优点: 孩子们继承了设置者,所以属性可以很容易地被覆盖以影响施工后的行为。 每一个二传手必须显式调用每一个属性: 多个属性可以以统一的方式头也不抬不同的方法签名(JavaBean规范)

缺点指定。 导致某些具有大量明确设置的属性的类。

0

您还可以使用@Resource自动装配,而不是@Autowired,这个工作有点像自动装配绰号,所以你不必担心,如果有更多的豆类与同类型(OFC你也可以处理与@Qualifier,但我只会建议描述一个bean的特性)。这取决于你的使用情况,哪种方式最好,因此你必须根据你的情况对它进行评估,然后再决定。

相关问题