2011-08-01 43 views
2

我想在我的服務層實現一個通用的抽象類。我已經在我的dao圖層中使用了一個simliar模式,它工作正常。我在Spring in Practice v8電子書中找到了一個實例。我想知道是否有辦法自動調用以下工作代碼。 (代碼工作,但我打電話給我的助手方法「setDao」之前,我在課堂上使用的任何其他方法)春季3服務道層與抽象類問題

測試類:

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

而不必調用方法(setDao())以允許您的子類將DAO引用傳遞給您的超類,爲什麼顛倒方向並強制子類將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

順便說一句,關於你的AbstractService - 看起來好像你的通用DAO和服務接口有幾乎相同的方法定義。這有什麼意義 - 如果大量的服務方法只是調用DAO方法,爲什麼還要爲DAO提供一個單獨的服務層呢?每個使用AbstractService的類是否真的需要能夠訪問'count()'或'findAll()'方法?我建議考慮減少這個抽象類中可用的服務層方法的大小,並且只編寫真正需要的方法 - 應該減少很多代碼。 –

+0

謝謝。這確實更有意義。 – blong824

1

嘗試使你的MyServiceImpl實施的InitializingBean,並改變你的setDao()方法是的afterPropertiesSet()。在框架完成調用setter之後它會自動調用。或者,(甚至更簡單),只需在setHeaderDao(...)方法中調用setDao()即可。

+0

我試過你的第二個建議,並引發一個空指針異常。我現在會嘗試你的第一個建議。我試圖找到一個乾淨的Spring方法來實現類來聲明要使用的dao,然後在抽象類中使用泛型crud操作。 – blong824

+0

實現InitializingBean工作,它讓我刪除我的測試類中的調用。我認爲這應該工作。你之前使用過一種模式嗎?我只是認爲在服務之間提取simliar代碼是有道理的。 – blong824

+0

我還沒有完成通用道,但它是有道理的。 InitializingBean是框架注入所有值之後執行代碼的標準Spring方法。很高興它對你有效。 – Kevin

0

將spring framework版本升級到4,問題就解決了。
檢查this頁面。

+0

您應該將鏈接中的「關鍵點」放入您的答案中,並將鏈接作爲參考。另外,解釋爲什麼會有效果。 – 2015-12-18 16:04:13