2017-09-27 6 views
1

Mybatis를 사용하고 Spring Boot 응용 프로그램을 개발 중입니다. Mybatis에 의해 인스턴스화 된 객체의 불변성을 보장하기 위해 Mybatis는 객체를 변경할 수 있도록하는 setter 대신 <constructor>을 사용합니다. 다른 서수 오브젝트와 마찬가지로이 Mybatis로 인스턴스화 된 오브젝트는 책임을 수행하기 위해 종속성이 필요하며 이러한 종속성은 때때로 Spring에 의해 인스턴스화 된 bean입니다.Mybatis에서 인스턴스화 한 변경 불가능한 도메인 객체에 종속성을 어떻게 주입해야합니까?

개체가 Spring에 의해 인스턴스화되면 종속성을 쉽게 주입 할 수 있습니다. 그러나 Mybatis에 의해 인스턴스화 된 객체는 분명히 Spring의 DI 컨테이너 밖에 있으며, @Autowired 또는 다른 Spring 메카닉을 사용하여 종속성을 주입 할 수 없습니다. 내가 수동으로 MyBatis로하여 인스턴스화 한 후 종속성을 삽입 할 수 물론

좋아 :

DomainA d = DomainAMapper.fetchOne(); 
d.setDependency(dependency); 

하지만이 DomainA의 불변성을 나누기.

불변성을 유지하면서 Mybatis 인스턴스화 된 객체에 종속성을 주입하려면 어떻게해야합니까?

+0

관리하려는 "종속성"과 동일한 예제를 공유 할 수 있습니까? 예를 들어, DomainA의 몇 가지 종속성을 알려주십시오. – Rafa

+0

@Rafa 의견을 보내 주셔서 감사합니다. 나는 여기서 DomainA 클래스에서 사용되는 다른 클래스와 같은 의존성을 의미합니다. 현재의 상황에서는 C++로 작성된 네이티브 모듈의 자바 래퍼 클래스입니다. 단위 테스트를 더 쉽게하기 위해 주입하고 싶습니다. – umainyosu

답변

1

현재 디자인에 만족하고 테스트에 집중한다면 PowerMockit은 개인 회원을 "설정/모의 할"수 있으므로 필요에 따라야합니다.

예 : 메모 측면


import org.powermock.api.support.membermodification.MemberModifier; 
...  
@RunWith(SpringRunner.class) 
@SpringBootTest 
public class DemoApplicationTests { 
    @Autowired 
    ApplicationContext contextToInject; 
    @Autowired 
    DomainA domainAAutowired; 

    @Test 
    public void contextLoads() throws IllegalArgumentException, IllegalAccessException { 
     // Autowired spring beans work fine 
     assertTrue(domainAAutowired.isContextInitilized()); 
     // Class out of spring context won't initialize dependencies 
     DomainA domainOutOfSpringContext = new DomainA(); 
     assertFalse(domainOutOfSpringContext.isContextInitilized()); 
     // We can 'set' private members using PowerMock 
     MemberModifier.field(DomainA.class, "context").set(domainOutOfSpringContext, contextToInject); 
     assertTrue(domainOutOfSpringContext.isContextInitilized()); 
    } 
} 

@Component 
public class DomainA { 
    @Autowired 
    private ApplicationContext context; 
    public boolean isContextInitilized() { 
     return context != null; 
    } 
} 
, 클래스의 MyBatis 간단한 POJO에 있어야한다. MyBatis에서 스프링 의존성을 가지는 것은 지속성 계층에만 관심을 기울여야하기 때문에 우려를 덜어주는 지표가 될 수 있습니다.

+0

답변 해 주셔서 대단히 감사합니다. 그리고 MyBatis에서 스프링 의존성을 갖는 것이 우려 사항의 분리를 나타내는 지표가 될 수 있습니다. 귀하가 지속 층에만 관심을 가져야한다는 사실은 제게 의미가 있습니다. 그러나 그런 의미에서 Mybatis 객체를 생성 할 때 getter와 setter가 있어야하고 다른 클래스에 로직을 한정해야합니까? [빈혈 도메인 모델] (https://www.martinfowler.com/bliki/AnemicDomainModel.html)을 피할 수있는 방법이 있습니까? – umainyosu

+1

MyBatis 인터페이스는'저장소 '로, MyBatis 클래스는'엔터티'로 생각하십시오. 그런 다음 스프링 종속성을 포함하는보다 자연스러운 장소 인 'Service'레이어를 만듭니다. 'Service' 레이어는 얇지 만 다른 리소스에 위임 할 수 있어야합니다. 'Service' 레이어가 당신의 리소스를위한'Facade'라고 상상할 수도 있습니다. – Rafa

+0

답변 해 주셔서 다시 한 번 감사드립니다. '서비스 계층은 얇지 만 다른 자원에 위임 할 수 있어야한다. ' 그렇다면이 논리 흐름이 가능한 예가 될 수 있습니까? 1) 서비스 클래스는 DB로부터 Entity를 가져 오기위한 저장소를 호출한다. 2) Service 클래스는 가져온 Entity를 포함하는 Domain 객체를 인스턴스화하기 위해 몇몇 factory를 호출한다. 3) Service 클래스는 비즈니스 로직을 수행하기위한 Domain 객체의 메소드를 호출한다. – umainyosu