복붙노트

[SPRING] 스프링 IoC 및 일반 인터페이스 유형 [중복]

SPRING

스프링 IoC 및 일반 인터페이스 유형 [중복]

다음과 같은 인터페이스로 Spring IoC를 사용하려고한다.

public interface ISimpleService<T> {
    void someOp(T t);
    T otherOp();
}

Spring이 제네릭 형식 인수 T를 기반으로 IoC를 제공 할 수 있습니까? 내 말은, 다음과 같은 것입니다 :

public class SpringIocTest {
    @Autowired
    ISimpleService<Long> longSvc;

    @Autowired
    ISimpleService<String> strSvc;
    //...
}

물론 위의 예제가 작동하지 않습니다.

expected single matching bean but found 2: [serviceLong, serviceString]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:243)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:957)

내 질문 : 인터페이스 또는 구현 클래스에 최소한의 수정으로 비슷한 기능을 제공 할 수 있습니까? 예를 들어 @Qualifiers를 사용할 수 있음을 알고 있지만 가능하면 간단하게 유지하려고합니다.

해결법

  1. ==============================

    1.나는 이것이 지워서 가능하다고 믿지 않습니다. 전체 autowiring을 수행 할 때 일반적으로 강력한 유형의 하위 인터페이스로 전환했습니다.

    나는 이것이 지워서 가능하다고 믿지 않습니다. 전체 autowiring을 수행 할 때 일반적으로 강력한 유형의 하위 인터페이스로 전환했습니다.

    public interface LongService extends ISimpleService<Long> {}
    public interface StringService extends ISimpleService<String> {}
    

    이 스위치를 수행 할 때 우리는 "사용량 찾기"를 훨씬 잘 추적 할 수있게 해주었 기 때문에 제네릭 인터페이스로 느슨해 진 것이므로 실제로이 기능이 실제로 마음에 드는 것을 발견했습니다.

  2. ==============================

    2.한정자 없이는 불가능하다고 생각합니다.

    한정자 없이는 불가능하다고 생각합니다.

    아프다 genericDAO로 내 솔루션을 표시하려고 시도합니다. 조금 자세하면 유감스럽게 생각합니다.

    인터페이스 및 구현 클래스 정의

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

    Spring bean 정의, abstract = "true"를 주목하라.

    <bean id="genericHibernateDAO" class="de.optimum24.av.pers.ext.hibernate.dao.GenericDAOImpl"
          abstract="true">
        <description>
            <![CDATA[
                Definition des GenericDAO.
            ]]>
        </description>
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    

    특수 구현 클래스없이이 genericDAO 사용

     <bean id="testHibernateChildDao" class="de.optimum24.av.pers.ext.hibernate.dao.GenericDAOImpl">
        <property name="sessionFactory" ref="sessionFactory" />
        <constructor-arg>
            <value>de.optimum24.av.pers.test.hibernate.domain.TOChild</value>
        </constructor-arg>
    </bean>
    

    concrete 클래스를 가진 constructor-arg에 주목하십시오. Spring Annotation으로 작업 할 경우 :

    @Autowired
    @Qualifier(value = "testHibernateChildDao")
    private GenericDAO<TOChild, Integer> ToChildDAO;
    

    genericDao Beans의 다양한 버전을 구별 할 수 있습니다 (Beanname을 직접 참조하여 한정어에 주목하십시오)

    특수 구현 클래스에서이 genericDAO 사용

    인터페이스와 클래스

    public interface TestHibernateParentDAO extends GenericDAO<TOParent, Integer>{
      void foo();
    }
    public class TestHibernateParentDAOImpl extends GenericDAOImpl<TOParent, Integer>
                                  implements TestHibernateParentDAO {
      @Override
      public void foo() {
          //* no-op */
      }
    }
    

    Bean 정의, 위의 추상 genericDAO에 대한 "부모"참조

    <bean id="testHibernateParentDao" class="de.optimum24.av.pers.test.hibernate.dao.TestHibernateParentDAOImpl"
          parent="genericHibernateDAO" />
    

    Spring Annotation 사용법 및 사용법

    @Autowired
    private TestHibernateParentDAO ToParentDAO;
    
  3. ==============================

    3.제네릭 형식이 컴파일 타임에 완전히 구체화되면 지우는 방법으로이 작업을 수행 할 수 있습니다. 이 경우 유형 정보는 다음 중 하나를 통해 사용할 수 있습니다.

    제네릭 형식이 컴파일 타임에 완전히 구체화되면 지우는 방법으로이 작업을 수행 할 수 있습니다. 이 경우 유형 정보는 다음 중 하나를 통해 사용할 수 있습니다.

    Class#getGenericInterfaces()
    Class#getGenericSuperclass()
    

    이것은 봄에 빠진 Guice의 주요 특징입니다.

  4. ==============================

    4.인터페이스를 일반적인 것으로 만들지 마십시오. 대신 방법을 만드십시오.

    인터페이스를 일반적인 것으로 만들지 마십시오. 대신 방법을 만드십시오.

    public interface ISimpleService {
        public <T> T doSomething(T param);
    }
    

    희망이 도움이됩니다.

  5. ==============================

    5.특정 지속성 레이어에서이를 수행 할 때 스프링 데이터가이를 수행합니다. Spring Data는 JPA, Neo4j, MongoDB 또는 지원하는 다른 기능을 사용하는 경우 시간 절약 및 단순화 도구로 유용합니다.

    특정 지속성 레이어에서이를 수행 할 때 스프링 데이터가이를 수행합니다. Spring Data는 JPA, Neo4j, MongoDB 또는 지원하는 다른 기능을 사용하는 경우 시간 절약 및 단순화 도구로 유용합니다.

  6. ==============================

    6.또 다른 옵션은 bean을 구현하는 인터페이스에 한쪽에 이름을 붙이고 다른쪽에 생성 된 이름을 가리키는 한정어로 주석을다는 것입니다 :) 다음은 프로젝트에서 사용하고있는 간단한 예입니다.

    또 다른 옵션은 bean을 구현하는 인터페이스에 한쪽에 이름을 붙이고 다른쪽에 생성 된 이름을 가리키는 한정어로 주석을다는 것입니다 :) 다음은 프로젝트에서 사용하고있는 간단한 예입니다.

     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;
    
  7. from https://stackoverflow.com/questions/502994/spring-ioc-and-generic-interface-type by cc-by-sa and MIT license