How to inject a service within abstract class using generics
I am attempting to create a generic abstract service class that provides common crud operations to my service layer by bringing together Service layer Objects (DTO?), Data layer Entities and their corresponding DAOs.
The DAO layer is standard-issue abstraction where my DAOs extend an AbstractJpaImpl:
@Repository
public abstract class AbstractJpaBaseDaoImpl<K extends Serializable, E> implements BaseDao<K, E> {
//Dao implementation
}
The DAOs extend this class and implement their respective dao interface that extends BaseDao.
I wish to create something similar in my service layer, but how would i inject the dao itself?
public abstract class AbstractBaseCrudServiceImpl<K extends Serializable, B extends AbstractBaseCrudBean, P, D extends AbstractJpaBaseDaoImpl<K,P>>
implements BaseCrudService<K, B> {
protected Class<B> businessObject;
protected Class<P> persistObject;
protected Class<D> dao;
@SuppressWarnings("unch开发者_开发技巧ecked")
public AbstractBaseCrudServiceImpl() {
//Extract the class type by accessing this classes parameters by index <0,1...> so 0 is K and 1 is E.
this.businessObject = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.persistObject = (Class<P>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[2];
this.dao = (Class<D>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[3];
}
//stuff ...
@Transactional
@SuppressWarnings("unchecked")
@Override
public void remove(B businessObject) {
logger.debug("Remove " + getBusinessObjectCanonicalName() + " id= " + businessObject.getId());
try {
getDao().remove(businessObject.getId()); //DOES NOT RECOGNIZE REMOVE METHOD
} catch (Exception e) {
logger.error("Unable to delete " + getBusinessObjectCanonicalName() + " record id=" + businessObject.getId(), e);
}
}
//stuff ...
}
Whats the cleanest way to inject a service within this abstract using generics?
D extends AbstractJpaBaseDaoImpl aint cutting it. Is there a pattern i can follow?
You may try using the @PostConstruct annotated method to wire the variable in the base abstract classes with real instantiated beans. These abstract classes can contacin basic CRUd operation implementations. Example code provided below. I hope I helped your query in some way.
@PostConstruct public void setupService() {
baseDao = userDao;
}
What are the definitions of some of the other types? Such as AbstractBaseCrudBean, BaseCrudService, etc.? There are so many compilation errors it is hard to get down to what your root issue is.
However, the reason the simple generic declaration is not cutting it is that there is no instance on which to invoke the methods of D. You would need something like:
private final D dao;
And then decorate that with @Inject @Named (since after erasure you will likely have many DAO's of the same type). So, each implementation of a DAO will need to have a unique string name, which may or not be a big deal.
精彩评论