Java Spring IoC和通用接口类型
我正在尝试使用Spring IoC,其界面如下:Java Spring IoC和通用接口类型,java,spring,inversion-of-control,types,generics,Java,Spring,Inversion Of Control,Types,Generics,我正在尝试使用Spring IoC,其界面如下: public interface ISimpleService<T> { void someOp(T t); T otherOp(); } public class SpringIocTest { @Autowired ISimpleService<Long> longSvc; @Autowired ISimpleService<String> strSvc;
public interface ISimpleService<T> {
void someOp(T t);
T otherOp();
}
public class SpringIocTest {
@Autowired
ISimpleService<Long> longSvc;
@Autowired
ISimpleService<String> strSvc;
//...
}
我的问题是:是否可以在对接口或实现类进行最小修改的情况下提供类似的功能?例如,我知道我可以使用@Qualifiers,但我想让事情尽可能简单。我认为由于擦除,这是不可能的。在进行完全自动布线时,我们通常会切换到强类型子接口:
public interface LongService extends ISimpleService<Long> {}
public interface StringService extends ISimpleService<String> {}
公共接口LongService扩展ISimpleService{}
公共接口StringService扩展ISimpleService{}
在做了这个切换后,我们发现我们实际上非常喜欢它,因为它允许我们更好地进行“查找使用情况”跟踪,这是泛型接口所没有的。如果没有限定符,我认为这是不可能的 我会尝试用一个通用DAO来展示我的解决方案,如果有点详细的话,很抱歉 接口和实现类定义
public interface GenericDAO<T, ID extends Serializable> (...)
public class GenericDAOImpl<T, ID extends Serializable>
implements GenericDAO<T, ID>
(...) important is this constructor
public GenericDAOImpl(Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
不要让你的界面泛化。而是让你的方法:
public interface ISimpleService {
public <T> T doSomething(T param);
}
公共接口是简单的服务{
公共T剂量测定(T参数);
}
希望有帮助。如果泛型类型在编译时完全具体化,则可以通过擦除来实现这一点。在这种情况下,可通过以下任一方式获取类型信息:
Class#getGenericInterfaces()
Class#getGenericSuperclass()
这是Spring中缺少的Guice的主要功能。在对某些持久性层执行此操作时,会为您执行此操作。如果您使用的是JPA、Neo4j或MongoDB,Spring数据是一个非常省时和简化的工具,或者它支持的其他东西。另一个选项是在一侧用名称注释实现bean的接口,并在另一侧用指向已创建名称的限定符注释:)下面是我在项目中使用的一个快速示例:
public interface IDAO<T> {
public void insert(T model);
public void update(T model);
public void delete(T model);
}
实体用户抽象类的实现:
@Repository(value = "userRepository")
public class UserDAO extends AbstractHibernateDAO implements IDAO<User> {
@Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void insert(User user) {
currentSession().save(user);
}
@Override
public void update(User user) {
currentSession().update(user);
}
@Override
public void delete(User user) {
currentSession().delete(user);
}
@Repository(value=“userRepository”)
公共类UserDAO扩展抽象HibernateDao实现IDAO{
@自动连线
公共用户DAO(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
@凌驾
公共作废插入(用户){
currentSession().save(用户);
}
@凌驾
公共无效更新(用户){
currentSession().update(用户);
}
@凌驾
公共作废删除(用户){
currentSession().delete(用户);
}
}
最后,正确实施:
@Resource
@Qualifier(value = "userRepository")
IDAO<User> userPersistence;
@Resource
@限定符(value=“userRepository”)
IDAO用户持久性;
您如何处理代码重复?可能有一个中产阶级也是普通的,不是吗?TK唯一需要的复制是标记接口。但是你没有展示你的实现类,所以我不知道你是否在做我看不到的事情!这个实现将适合另一个问题:)这是一个很好的答案,涉及到注释和XML的用法。从长远来看,这个解决方案对你有效吗?如果使用这种方法有任何缺点,比如能够更容易地跟踪代码(Krosenvold在第1篇文章中提到)?这更像是一个组织/知识问题,如果开发人员知道它的工作流程,那么这种通用方法肯定比使用(标记)更难处理从Spring4.0开始,interfacesIt现在似乎成为可能。请参阅本文和Spring的文章。
<bean id="testHibernateParentDao" class="de.optimum24.av.pers.test.hibernate.dao.TestHibernateParentDAOImpl"
parent="genericHibernateDAO" />
@Autowired
private TestHibernateParentDAO ToParentDAO;
public interface ISimpleService {
public <T> T doSomething(T param);
}
Class#getGenericInterfaces()
Class#getGenericSuperclass()
public interface IDAO<T> {
public void insert(T model);
public void update(T model);
public void delete(T model);
}
public abstract class AbstractHibernateDAO {
protected SessionFactory sessionFactory;
protected Session currentSession() {
return sessionFactory.getCurrentSession();
}
}
@Repository(value = "userRepository")
public class UserDAO extends AbstractHibernateDAO implements IDAO<User> {
@Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void insert(User user) {
currentSession().save(user);
}
@Override
public void update(User user) {
currentSession().update(user);
}
@Override
public void delete(User user) {
currentSession().delete(user);
}
@Resource
@Qualifier(value = "userRepository")
IDAO<User> userPersistence;