1

我们有一个接口:

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。问题是在我们应用程序的其他任何地方,我们都是自动装配接口,而不是类。从我读到的内容来看,总的来说这是一个好主意。事实上,我已经尝试将 NotifyService 重写为 Abstract 类,然后让 EmailNotifyService 扩展它。但是 Spring 没有正确地自动装配它,它没有像为接口创建代理一样,而且我所有的 Autowired 字段都是空的。

所以看起来我们被自动装配 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 中的所有 Autowired 字段( PersonRepository, others ...) 为空。当我使用接口时,所有 Autowired 字段都正确连接。

但我的主要问题是我曾经明确地使用具体类,使用构建器直接创建一个新的 EmailNotifyService(),并将信息传递给它——Person、EmailType 和 Event。这些只是普通的豆子。在 EmailNotifyService 中没有针对它们的 setter/getter,但是有 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 对它们一无所知?

目前我们在 web 应用程序中使用邮件服务,但理论上邮件服务应该能够独立工作。无论如何,我看不到请求范围的 bean 如何在这里帮助我。

4

1 回答 1

0

罗伯特不正确自动装配是什么意思?你有什么错误吗?

一般来说,接口和类的自动装配都可以在 Spring 中工作,除非你有一些 autoproxy 配置的例子@Transactional

您不需要在您的界面中有 setPerson()、setEmailType() 等,而是在需要它们的具体类中自动装配它们。

但似乎 Person 不是一个服务,而是一个持有数据及其特定于请求的 bean。如果您的应用程序是 Web 应用程序,那么请查看请求范围代理以注入 Person like bean。


因此,您正在使用事务,这就是基于类的注入失败的原因。添加proxy-target-class="true"tx:annotation-driven.

关于您的注入,Person然后EmailType您必须对 bean 执行此操作EmailNotifyService。在EmailNotifyService我没有看到任何PersonEmailType变量定义。另请阅读我在上面所说的关于 Person bean 的内容。


你的设计不正确。您不应该制作EmailBuilderbean 并希望自动装配到EmailNotifyService. 相反,EmailNotifyService您应该有一个方法send(EmailBuilder builder),您可以在其中传递您在某处动态创建的构建器。

于 2013-04-16T04:26:57.273 回答