2011-08-01 6 views
2

私はサービスレイヤーに汎用抽象クラスを実装しようとしています。私はすでに私のDAO層でsimliarパターンを使用しており、それは正常に動作します。私はSpringのPractice v8 ebookの実例を見つけました。私は、次の作業コードをオートワイヤリングする方法があるのだろうかと思っています。 (コードは動作しますが、私は、私はクラスのどのメソッドを使用する前に、私のヘルパーメソッド 'setDao' を呼び出す必要があります)Spring 3サービス抽象クラスの質問を持つDaoレイヤー

Testクラス:

public class App { 


    public static void main(String[] args) { 
     ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml"); 

     MyService service = (MyService)appContext.getBean("myService"); 

     service.setDao(); 

     Heading detail = new Heading(); 
     detail.setName("hello"); 

     service.save(detail); 

     Heading dos = service.findById(Long.valueOf(1)); 
     System.out.println(dos); 
    } 
} 

MyServiceImplクラス

@Service("myService") 
public class MyServiceImpl extends AbstractServiceImpl<Heading> implements HeadingService { 

    @Autowired 
    private HeadingDao headingDao; 

    public void setHeadingDao(HeadingDao headingDao) { 
     this.headingDao = headingDao; 
    } 

    public void setDao() { 
     super.setDao(this.headingDao); 
    } 

} 

たMyServiceインターフェース

public interface HeadingService extends AbstractService<Heading> { 
    public void setDao(); 
} 

AbstractServiceImplクラス

@Service 
public abstract class AbstractServiceImpl<T extends Object> implements AbstractService<T> { 

    private AbstractDao<T> dao; 

    public void setDao(AbstractDao<T> dao) { 
     this.dao = dao; 
    } 

    public void save(T t) { 
     dao.save(t); 
    } 

    public T findById(Long id) { 
     return (T)dao.findById(id); 
    } 

    public List<T> findAll() { 
     return dao.findAll(); 
    } 

    public void update(T t) { 
     dao.update(t); 
    } 

    public void delete(T t) { 
     dao.delete(t); 
    } 

    public long count() { 
     return dao.count(); 
    } 

} 

AbstractServiceインタフェース

public interface AbstractService<T extends Object> { 

    public void save(T t); 
    public T findById(Long id); 
    public List<T> findAll(); 
    public void update(T t); 
    public void delete(T t); 
    public long count(); 

} 

答えて

4

サブクラスがDAO参照をスーパークラスに渡すためのメソッド(setDao())を呼び出す代わりに、その方向を逆にしてサブクラスがスーパークラスにDAOを供給するように強制するのはなぜですか?例えば

public abstract class AbstractServiceImpl<T extends Object> implements AbstractService<T> { 
    private AbstractDao<T> dao; 

    abstract AbstractDao<T> getDao(); 

    public void save(T t) { 
     getDao().save(t); 
    } 
} 

public class FooServiceImpl extends AbstractServiceImpl<Foo> { 
    @Autowired 
    private FooDao fooDao; 

    @Overrides 
    public AbstractDao<Foo> getDao() { 
     return fooDao; 
    } 
} 

行動に参照渡しチェーンをキックする外部メソッドを呼び出す必要はありません。

+0

Btw、あなたのAbstractServiceについて - あなたの汎用DAOとサービスインタフェースがほぼ同じメソッド定義を持っているかのようです。何がポイントですか?大量のサービスメソッドがDAOメソッドを呼び出すだけであれば、DAOとは別のサービスレイヤを持つのはどうですか? AbstractServiceを使用するすべてのクラスは実際に 'count()'または 'findAll()'メソッドにアクセスできる必要がありますか?私は、この抽象クラスで利用可能なService-Layerメソッドのサイズを減らすことを検討し、真に必要な記述メソッドのみを使用することで、多くのコードを削減することをお勧めします。 –

+0

ありがとうございます。それは理にかなっています。 – blong824

1

あなたMyServiceImplがInitializingBeanを実装して作ってみましょう、とafterPropertiesSetであるためにあなたのsetDao()メソッドを変更します()。フレームワークがsetterを呼び出した後、自動的に呼び出されます。

setHeaderDao(...)メソッドでsetDao()を呼び出すだけで簡単です。

+0

私はあなたの2番目の提案を試み、それはnullpointer例外をスローします。私は今あなたの最初の提案を試みます。私は実装クラスのために、どのようなDAOを使用するのかを宣言し、その後抽象クラスで一般的なcrudオペレーションを使用するために、きれいなSpringの方法を見つけようとしていました。 – blong824

+0

InitializingBeanの実装が機能し、テストクラスの呼び出しを削除できます。私はこれがうまくいくと思います。この前にsimliarパターンを使用しましたか?私はちょうどそれがサービス間のsimliarコードを引き出すことが理にかなっていると思った。 – blong824

+0

私は一般的なDAOを行っていませんが、理にかなっています。 InitializingBeanは、フレームワークがすべての値を注入した後にコードを実行する標準的な方法です。うれしいことはあなたのために働いた。 – Kevin

0

スプリングフレームワークのバージョンを4にアップグレードすると、問題は解決されます。
チェックthisページ。

+0

リンクから「キーポイント」を回答に入力し、そのリンクを参考にしてください。また、何かがうまくいく理由を説明してください。 –

関連する問題