![](/img/trans.png)
[英]Spring dependency injection doesn't work in ConstraintValidator
[英]Doesn't Spring's dependency injection break information hiding?
来自C ++背景我必须掌握Java世界及其框架的复杂性。 看一下DI的弹簧框架,我发现我很难相信我必须制作每个将受DI公众影响的setter功能。 这种要求是否违反了信息隐藏原则?
当然我希望spring能够设置我的类的一些私有部分,但我当然不希望每个客户端类都能够做同样的事情。
我在这里错过了什么?
我同意你的观点 - 这就是为什么我更喜欢构造函数注入。
如果您对接口进行编码 ,则只需要在实现上公开setter。 当您将接口注入系统的其他部分时,它们无法访问实现细节或对象的状态。
你(可能)必须制作一个制定者,它会告诉你一些内部细节,但是没有必要制作一个吸气剂。 所以你要透露一些信息,但不是太多; 除了预期目的之外,它对任何事情都没有用。
另外,我建议使用注释和@Autowired,在这种情况下,您不需要创建公共setter。
如果您使用spring注释(@Autowired),您可以使用DI私人成员。
如果你在我的视图中使用松耦合和(单元)可测试弹簧DI会打破不应隐藏的信息。
从未使用@Autowired,我倾向于喜欢在构造函数中使用参数,但有时很难理解参数的含义,特别是如果你有很多参数 - 在这种情况下,我更喜欢使用Effective中描述的“Builder”方法Java的。 构造函数接收构建对象(具有setter),并使用它构造自身。 类的注入属性是final(immutability),“Builder”类包含setter但不包含getter(它不需要我们将它声明为正在构造的类的内部类),并且不需要setter为Spring创建:
<bean id="runnable" class="MyClass">
<constructor-arg>
<bean class="MyClass$Builder">
<property name="p1" value="p1Value"/>
<property name="p2" value="p2Value"/>
<property name="p3" value="p3Value"/>
<property name="p4" value="p4Value"/>
</bean>
</constructor-arg>
</bean>
班级代码:
public class MyClass {
private final String p1;
private final String p2;
private final String p3;
private final String p4;
public MyClass(Builder builder) {
this.p1 = builder.p1;
this.p2 = builder.p2;
this.p3 = builder.p3;
this.p4 = builder.p4;
}
...
public static class Builder {
private String p1;
private String p2;
private String p3;
private String p4;
public void setP1(String p1) {
this.p1 = p1;
}
... and so on
}
}
不同意Spring打破封装的观点。 即使你有pojo你已经获得并在课堂上暴露并且第三方消耗你的jar,仍然有可能jar的使用者做同样的事情,这可能是Spring bean配置。 (对于任何其他OOP语言都是如此)
Spring只提供了可以通过代码完成的方法,并且该控件移出了代码(IOC)。
消费者(考虑其他程序员使用你的库),通过spring配置创建bean,你的代码仍然可以控制。 没有正文阻止你验证用户给出的输入(spring IOC框架也会通过setter中的其他类调用你的setter来完成相同的代码)。
public void setAge(int age) {
if ( age < 0 ) {
throw new AppException("invalid age!");
}
this.age=age;
}
只是想提一下,我(无意中)发布了这个问题的更通用的版本,并且它对该问题有一些进一步的见解: 必须依赖注入以牺牲封装为代价吗?
这是我更喜欢Guice的另一个原因;)Guice和Spring都实现了JSR 330 DI规范,但是使用Guice我可以注入我的私有实例字段而没有setter,我真的不喜欢构造函数注入,因为它似乎更难重构。 在我的拙见中,这也只是更多的打字而没有多少价值。
后来,迪恩
我想这是一个权衡。 您可以减少硬连线依赖性,但是您可能会暴露实现的内容。 使用正确的抽象,您也可以减少它,但随后增加代码库的复杂性(例如,具有可以是LDAP连接或SQL连接的通用“连接”)。
就个人而言,我不认为使用构造函数注入有助于它,因为它更具概念性。
我将不得不查看@Autowire,tho'。
TJ
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.