java – 在Spring IoC中注入基于实体的类的正确方法是什么

请多多包涵:

我们有一个Hibernate和Spring IoC的设置,其中对于每个实体(用户,客户,账户,支付,优惠券等),有一堆“单例”接口和支持它的实现类.
例如:forCustomer:

@Entity
public class Customer extends BaseEntity {
  ...
  public name();
}

/* base API */
public interface Service {
  public create();
  public list();
  public find();
  public update();
  public delete();
}

/* specific API */
public interface CustomerService extends Service {
  public findByName();
}

/* specific implementation */
public class CustomerServiceImpl extends BaseService implements CustomerService {
  ...
}

这种模式一直在继续(CustomerManager,CustomerDataProvider,CustomerRenderer等).

最后,为了针对特定API的实例(例如CustomerService.findByName()),一个静态的全局持有者已经发展 – 这使得像下面这样的引用可用:

public class ContextHolder {
  private static AbstractApplicationContext appContext;

  public static final CustomerService getCustomerService() {
      return appContext.getBean(CustomerService.class);
  }
  //... omitting methods for each entity class X supporting class 
}

@Configuration
public class ServicesConfiguration {
  @Bean(name = "customerService")
  @Lazy(false)
  public CustomerService CustomerService() {
      return new CustomerServiceImpl();
  }
  //... omitting methods for each entity class X supporting class 
}

所以,问题是:

什么是注入这些支持类的正确方法,例如CustomerService,给定实体实例,用于以下用途:

>我有一个特定的实体(例如客户),并希望获得服务并调用特定的API(例如findByName())?
>我有一个实体(不关心具体是哪一个),并且想要调用一般API(例如find())

所有这些,同时避免全局静态引用(因此,在例如测试中交换实现,并简化调用者代码).

如果我有一个实体实例,我可以获得任何支持类

BaseEntity entity = ... // not injected
Iservice service = ...// should be injected
service.create(entity);

或者,获取给定实体类型所需的所有支持类

/* specific implementation */
public class CustomerServiceImpl extends BaseService implements CustomerService {
  // inject specific supporting classes
  @Autowire CustomerManager manager;
  @Autowire CustomerDataProvider provider; 
  @Autowire CustomerRenderer renderer; 
  @Autowire CustomerHelper helper; 
  ...
}

并在其他方案中稍微更改配置

// how to configure Spring to inject this double?
Class CustomerManagerDouble extends CustomerManager {...}

@Autowired @Test public void testSpecificAPI(CustomerService service) {
  service.doSomethingSpecific();
  assert ((CustomerManagerDouble) service.getManager()).checkSomething();
}

最佳答案 我不完全确定你在问什么,但我认为你想用服务注入实体对象(由Hibernate创建),对吧?

如果是这种情况,请使用Spring 3.1文档中描述的@Configurable注释:

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-atconfigurable

请注意,您必须使用AspectJ编织实体类(加载时或编译时)才能使其正常工作.

点赞