4

我慢してください:

HibernateSpring IoCのセットアップがあり、各エンティティ ( UserCustomerAccountPaymentCouponなど) には、それをサポートする「シングルトン」インターフェースと実装クラスが多数あります。
Customer:

@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 {
  ...
}

そして、このパターンは何度も続きます ( CustomerManagerCustomerDataProviderCustomerRendererなど)。

最後に、特定の 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これらのサポート クラスを注入する適切な方法は何でしょう

  1. 特定のエンティティ (例: Customer) があり、サービスを取得して特定の API (例: ) を呼び出したいfindByName()ですか?
  2. エンティティがあり (特定のエンティティは気にしない)、一般的な 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();
}
4

1 に答える 1

2

あなたが何を求めているのか完全にはわかりませんが、(Hibernate によって作成された) エンティティ オブジェクトにサービスを注入したいと思いますよね?

その場合は、Spring 3.1 のドキュメントで説明されているように @Configurable アノテーションを使用します。

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

これを機能させるには、AspectJ を使用してエンティティ クラス (ロード時またはコンパイル時) を織り込む必要があることに注意してください。

于 2012-05-23T21:02:16.173 に答える