it-source

스프링 구성 클래스의 로드 순서를 적용하는 방법은 무엇입니까?

criticalcode 2023. 7. 10. 22:26
반응형

스프링 구성 클래스의 로드 순서를 적용하는 방법은 무엇입니까?

저는 스프링부트로 멀티 모듈 프로젝트(메이븐)를 진행하고 있습니다.각 모듈에는 자체 @Configuration 클래스가 있습니다.기본적으로 저는 다음과 같은 레이아웃을 가지고 있습니다.

foo-embedded 모듈(SpringApplication.run() 메서드만 호출하여 실행):

@Configuration
@EnableAutoConfiguration
@ComponentScan("de.foobar.rootpackage")
@Import({ApplicationConfig.class, RepositoryConfig.class, SecurityConfig.class})
public class FooApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(FooApplication.class, args);
    }
}

모듈 foo-common(모든 콩 및 스프링 데이터 jpa 초기화 구성 포함)

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement(entityManagerFactoryRef="entityManagerFactory")
public class RepositoryConfig {

    @Bean(destroyMethod = "shutdown")
    public DataSource getDataSource() {
        // returning a Hikari CP here
    }

    @Bean(name = "entityManagerFactory") // overriding spring boots default
    public EntityManagerFactory getEntityManagerFactory() {
        // returning a new LocalEntityManagerFactoryBean here
    }
}

foo-common에 대한 의존성이 큰 모듈 foo-security(스프링 보안 구성 및 관련 도메인 클래스 포함)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // configuring HTTP security and defining my UserDetailsService Bean
}

FooApplication 클래스를 사용하여 애플리케이션을 시작하면 모든 것이 예상대로 작동합니다.위에서 언급한 UserDetailsServiceImplget은 @EnableJpaResposities 주석을 통해 생성되는 내 UserRespository와 자동 배선됩니다.

통합 테스트를 작성하고 싶어서 모듈 중 하나에 테스트 클래스를 추가했습니다.

모듈 foo-media(일부 도메인 관련 항목 및 해당 모듈에 대한 테스트 사례 포함)

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {RepositoryConfig.class, SecurityConfig.class})
@WebAppConfiguration
@IntegrationTest
public class DirectoryIntegrationTest {
    // my test code
}

테스트를 실행하면 RepositoryConfig.class가 로드하기 전에 SecurityConfig가 로드되는 것 같습니다.보안 구성에서 자동 배선해야 하는 UserServiceImple을 정의했으므로 테스트가 다음으로 시작되지 않습니다.

NoSuchBeanDefinitionException telling me: No qualifying bean of type [com.foo.rootpackage.security.repository.UserRepository]

이미 추가하려고 했습니다.@DependsOn("UserRepository")의 정의에 입각하여UserDetailsService봄이 그런 이름의 콩을 찾을 수 없다고 말하는 것.

어떤 힌트나 도움이라도 주시면 감사하겠습니다!잘 부탁드립니다!

EDIT (더 많은 코드를 제공하라는 요청을 받았기 때문에) ----

테스트의 경우 실제 RepositoryConfig.class를 사용하지 않고 공통 모듈에 TestRepositoryConfig.class를 사용합니다.이렇게 보이는 것

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", basePackages = "de.foobar.rootpackage")
public class TestRepositoryConfig extends RepositoryConfig {

    @Bean
    @Override
    public DataSource getDataSource() {
        // returning the ds for testing
    }
}

사용할 수 있습니다.@Order구성 클래스에 주석을 추가하여 로드 순서를 정의할 수 있습니다.하지만 스프링이 적절한 질서를 해결해야 하기 때문에 이상합니다. 그러니 당신이 부동산 주입을 하는지 확인해주세요.UserRepositoryUserDetailsService

그래서 저는 이것을 해결할 수 있었습니다.지적했듯이 구성 클래스의 로드 순서와는 아무런 관련이 없습니다(처음 생각한 것입니다).

눈치채셨겠지만, 유일한 구성이 다음과 같습니다.@ComponentScan주석은 FooApplication입니다. 클래스 Spring은 어디를 찾아야 할지 몰라 리포지토리를 찾을 수 없습니다.다음과 같은 basePackages 특성 제공:

@EnableJpaRepositories(basePackages = "de.foobar.rootpackage")

TestRepositoryConfig.class에서 여기서 트릭을 수행했습니다.

언급URL : https://stackoverflow.com/questions/24287024/how-to-enforce-loading-order-of-spring-configuration-classes

반응형