我们有一个界面:
public interface NotifyService {
public void send();
一个实现它的类
public class EmailNotifyService implements NotifyService {
private EmailBuilder _builder;
@Autowired
PersonRepository _personRepository;
... other Autowired Repositories ...
public EmailNotifyService(EmailBuilder builder) {
this._builder = builder;
}
public void send() {
// send mail using _builder.getRecipient().getEmailAddress(), etc.
}
我们曾经使用构建器实例化EmailNotifyService:
public class EmailBuilder {
private Person _recipient;
private EmailType _type;
private Event _event;
public EmailNotifyService build() {
return new EmailNotifyService(this);
}
public EmailBuilder recipient(Person recipient) {
this._recipient = recipient;
return this;
}
......等等。但是现在,我们不是使用build()来创建新的EmailNotifyService,而是尝试使用Autowire和Spring。问题是我们的应用程序中的其他任何地方,我们都是Autowiring接口,而不是类。从我读过的内容来看,这是一个好主意。事实上,我已经尝试将NotifyService重写为Abstract类,然后让EmailNotifyService扩展它。但Spring并没有正确地自动装配它,它没有像接口那样创建代理,而且我的所有自动连接字段都是空的。
所以看起来我们仍然坚持使用NotifyService接口进行自动装配。精细。我无法理解的是 - 如何将我用于分配构建器的数据(Person,EmailType和Event)转换为Spring Autowired接口?
我想我可以将接口定义改为setPerson(),setEmailType()等,但除了真的很丑之外,它首先打败了使用接口的目的。不同的NotifyService(例如WebServiceNotifyService或RestNotifyService)之夜不需要该信息。
有没有优雅,最佳实践的方法来做到这一点?
感谢。
修改
我正在使用注释,非常少的xml。我也在使用事务管理,这可能解释了为什么抽象类没有正确自动装配?这是我在xml中唯一的相关信息:
<context:annotation-config />
<context:component-scan base-package="com.myco.myapp" />
<tx:annotation-driven transaction-manager="transactionManager"/>
当我说“自动装配不能正常工作”时,我的意思是当我尝试自动装配抽象类时,Spring似乎没有创建像接口那样的代理,以及所有自动连接字段我的EmailNotifyService(PersonRepository,其他......)为空。当我使用接口时,所有自动连接字段都正确连接。
但我的主要问题是我曾经使用构建器直接创建一个新的EmailNotifyService(),然后传递信息 - Person,EmailType和Event。这些只是普通的豆子。在EmailNotifyService中没有针对它们的setter / getters,但有EmailBuilder,它曾经存在于EmailNotifyService中。
但是现在我正在使用NotifyService接口,它对Person,EmailType或Event一无所知。但我需要此信息才能使EmailNotifyService正常工作。
所以我的问题是,如果我使用Spring来自动装配我的EmailNotifyService:
@Autowired
@Qualifier("email") // so Spring knows I want to use the EmailNotifyService implementation
NotifyService _notifyService
如何设置Person,EmailType和Event数据,因为NotifyService对它们一无所知?
目前我们在网络应用程序中使用邮件服务,但理论上邮件服务应该能够独立工作。无论如何,我不知道请求范围的bean如何帮助我。
答案 0 :(得分:0)
通常接口和类自动布线都在Spring中工作,除非你有一些autoproxy配置的例子@Transactional
。
您不需要在界面中使用setPerson(),setEmailType()等,而是将它们自动装配在需要它们的具体类中。
但似乎Person不是一个服务,而是一个保存数据及其特定于请求的bean。如果你的是一个Web应用程序,那么查看请求范围代理以注入像bean这样的人。
因此,您正在使用交易,这就是基于类注入失败的原因。将proxy-target-class="true"
添加到tx:annotation-driven
。
关于注入Person
和EmailType
,您必须对bean EmailNotifyService
执行此操作。在EmailNotifyService
中,我没有看到定义任何Person
或EmailType
个变量。另外阅读我上面关于Person bean的内容。
您的设计不正确。你不应该让EmailBuilder
成为一个bean,并且希望自动装配到EmailNotifyService
。相反,在EmailNotifyService
中,您应该有一个方法send(EmailBuilder builder)
,您可以在其中传递您在动态创建的构建器。