Spring依赖注入方式有Setter注入,构造函数注入。项目中如何选择?
先说结论:推荐用构造函数注入并在注入时判空;依赖服务是optional或者比较多时部分依赖可以考虑用setter(生命周期比被依赖服务短的)
setter依赖注入
早期Srping推荐用setter注入方式,spring参考例子中也大量使用。缺点是可能用到依赖服务时还未setter注入或者注入了空对象。解决空对象的一种方式是加入Spring 2.0 annotation @Required
public class Service {
private Collaborator collaborator;
@Required
public void setCollaborator(Collaborator c) {
this.collaborator = c;
}
}
或者
public class Service implements InitializingBean {
private Collaborator collaborator;
public void setCollaborator(Collaborator c) {
this.collaborator = c;
}
// from the InitializingBean interface
public void afterPropertiesSet() {
if (collaborator == null) {
throw new IllegalStateException("Collaborator must be set in order for service to work");
}
}
}
用setter注入的另外一个原因是构造函数注入不能直观指定依赖名字。
<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>
<bean id="accountService" class="com.mycompany.service.AccountService">
<property name="authenticator" ref="authenticator"/>
</bean>
<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>
<bean id="accountService" class="com.mycompany.service.AccountService">
<constructor-arg ref="authenticator"/>
</bean>
构造函数依赖注入
public Service(Collaborator collaborator) {
if (collaborator == null) {
throw new IllegalArgumentException("Collaborator cannot be null");
}
this.collaborator = collaborator;
}