简体   繁体   中英

Spring 3 Service Dao layers with abstract class question

I am trying to implement a generic abstract class in my service layer. I am already using a simliar pattern in my dao layer and it works fine. I found a working example in the Spring in Practice v8 ebook. I am wondering if there is a way to autowire the following working code. (The code works but I have to call my helper method 'setDao' before I use any other method in the class)

Test class:

    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 class

    @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 interface

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

AbstractServiceImpl class

    @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 interface

    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();

}

Instead of having to call a method ( setDao() ) to allow your subclass to pass the DAO reference to your superclass, why reverse the direction and force the subclass to supply the DAO to the superclass?

for example:

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;
     }
}

There is no need to call a method externally to kick the reference-passing-chain into action.

Try making your MyServiceImpl implement InitializingBean, and change your setDao() method to be afterPropertiesSet(). It will automatically get called after the framework is done calling setters.

Or, (even more simple), just call setDao() in your setHeaderDao(...) method.

Upgrade spring framework version to 4, and the problem will be solved.
check this page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM