3

我有一个实现 W 接口的 B 类。它具有 W 方法的默认实现。类 C 和 D 覆盖默认实现,它们需要一个服务,其 bean 由 spring 实例化。字符串 a 和 b 来自用户,因此我无法提前创建 B/C/D 的 bean。所以我有一个工厂,它根据用户参数创建一个新对象(它将根据参数创建 B/C/D)。有什么干净的方法可以从 C 和 D 内部使用服务 bean(aa/bb/cc/dd 等)(在服务器启动期间弹簧自动装配,当时实例化 B/C/D 所需的参数不可用)或有没有更好的方法来解决这个问题?

 Class B implements W{
      String a;
      String b;
      B (String a, String b);

      w_method(){

      }
   }

    Class C extends B {
      @Autowired
      Service aa;

      @Autowired
      Service bb;

      @Autowired
      Service cc;

      @override
      w_method(){
      }
    }

Class D extends B {
  @Autowired
  Service dd;

  @override
  w_method(){
  }
}
4

2 回答 2

8

有三种可能的方法:

  • 构造函数参数来自用户这一事实并不意味着这些对象不能由 Spring 创建。

    您可以将它们声明为范围的 Spring beanprototype并在您的工厂中执行以下操作:

    public C createC(String a, String b) {
        return applicationContext.getBean("c", a, b);
    }
    

    这种方法的一个缺点是你的工厂依赖于ApplicationContext.

  • @Configurable您可以使用AspectJ 编织来注释这些类并启用。在这种情况下,Spring 将配置这些类的对象,即使您使用new. 请参阅7.8.1 使用 AspectJ 通过 Spring 依赖注入域对象

  • 您可以手动触发自动装配

    applicationContext.getAutowireCapableBeanFactory().autowireBean(...);
    

    当您无法控制需要自动装配的对象(servlet 等)的创建时,这种方法很有用。

于 2012-04-25T08:58:08.593 回答
6

我认为最简单的方法是将服务连接到工厂并在返回它们之前调用 B / C / D 对象上的设置器,而不是尝试使用@Autowired.

或者使用 axtavt 的构造函数参数方法。如果你想避免依赖ApplicationContext,你可以使用Lookup Method Injection,但是你必须按照这篇博文修补 Spring:http: //nurkiewicz.blogspot.co.uk/2010/08/creating-prototype-spring- bean-on.html

于 2012-04-25T09:05:46.670 回答