2016-06-11 7 views
0

私はベストプラクティスを再利用するコードに従おうとしています。 は、私はいくつかの一般的な方法で、一般的なDAOインタフェースを持っている:サービスレイヤクラスを生成する

public interface DaoInterface<T> { 
     T findById(int id); 
     //...more methods... 
    } 

とその実装クラス:

public class GenericDao<T> implements DaoInterface<T> { 

     @SuppressWarnings("unchecked") 
     private final Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 

     @Autowired 
     protected SessionFactory sessionFactory; 

     @Override 
     @SuppressWarnings("unchecked") 
     public T findById(int id) { 
      Session session = sessionFactory.getCurrentSession(); 
      return (T) session.get(persistentClass, id); 
     } 

     //...more methods... 
    } 

その後、私のすべての具体的な実装クラスはGenericDaoを拡張し、そのインタフェースを実装しています。

私のアプリケーションにもサービスレイヤがあります。一部のサービスのメソッドは、DAOクラスにその作業を完全に委任します。したがって、具体的な各Service実装では、適切なDAOクラスをオートワイヤリングし、そのメソッドを呼び出します。 は、だから今に見えます:

public interface CustomerService { 
    Customer findById(int id); 
} 

と実装:

@Service 
@Transactional(readOnly = true, rollbackFor = Exception.class) 
public class CustomerServiceImpl implements CustomerService { 

    @Autowired 
    private CustomerDao customerDao; 

    @Override 
    public Customer findById(int id) { 
     return customerDao.findById(id); 
    } 
} 

私の質問は - どのようにDAOと同じようにサービスクラスをgenerifyしますか?私の具体的なクラスがなりますように:

@Autowired 
private GenericDao<T> dao; 

をので、私はdaoのメソッドを呼び出すことができること:

public class CustomerServiceImpl extends GenericService<Customer> implements CustomerService { 
..... 
} 

問題は、私は汎用サービスでDAOクラスをautowireすることができないということです。 私はコンストラクタでそれを行う必要がありますか?

もう1つの質問 - @Transactionalのメソッドに注釈を付ける適切な場所はどこですか - ジェネリッククラスまたはすべての実装クラスでですか?

+0

可能な回答が多すぎるか、この回答の回答が長すぎる可能性があります。回答セットを絞り込むか、いくつかの段落で回答できる問題を特定するための詳細を追加してください。 –

+0

主な質問は 'GenericService 'クラスの ''型の 'GenericDao'をどのようにautowireするのですか? – DimaSan

答えて

2

あなたは、一般的なダオのインスタンスを作成し、サービス層では、いくつかの決断に置く必要があります:あなたは良い一般的なリポジトリ層がSpring Data Jpa

この意志のために見てみる必要がある場合にも

@Repository 
public class GenericDao implements DaoInterface<T> { 
//The type must be aquired at runtime,otherwise it may not be thread safe 

    @Autowired 
    protected SessionFactory sessionFactory; 

    @Override 
    @SuppressWarnings("unchecked") 
    public T findById(int id,Class<?> persistenceClass) { 
     Session session = sessionFactory.getCurrentSession(); 
     return (T) session.get(persistenceClass, id); 
    } 

    //...more methods... 
} 

をGenericDaoの1つだけインスタンスにします。

次のあなたが持っている2選択肢:

  1. abstract class GenericService<T> { 
        @Autowired 
        protected GenericDao dao; 
        @SuppressWarnings("unchecked") 
        protected final Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    
        @Override 
        public T findById(int id) { 
         return dao.findById(id,persistenceClass); 
        } 
    } 
    

    今すぐあなたのサービス必見の一人一人が延びすべてのエンティティのためのクラスのサービスを作成し、すべてのニーズのためのシングルトンサービスを作成します。指定された永続性タイプを持つGenericServiceとそのジョブが完了しました。

+0

詳細な回答ありがとうございます!これが解決策です。さらにもう1つ質問します。子供のDAOクラスに '@ Repository'アノテーションを付けておくか、' GenericDao'から継承しますか? – DimaSan

+0

インスタンス化するすべての実装に@Repository(または他のSpring Bean Annotaion)を指定する必要はありません。 –

+0

私はそれを直接使用しないので、 'GenericDao'クラスでこの注釈を指定する必要はありません。私は正しい? – DimaSan

関連する問題