복붙노트

[SPRING] 세션 기반 데이터 소스가있는 스프링 부트

SPRING

세션 기반 데이터 소스가있는 스프링 부트

나는 웹 애플리케이션의 꽤 일반적인 유스 케이스가되어야하는 것으로 머리카락을 찢어 버렸다. 나는 REST Repository, JPA 등을 사용하는 Spring-Boot 애플리케이션을 가지고있다. 문제는 두 개의 데이터 소스가 있다는 것이다.

두 번째 데이터 소스는 인증 된 사용자에게 고유하므로, 인증 후 Principal 사용자에 따라 AbstractRoutingDataSource를 사용하여 올바른 데이터 소스로 라우팅하려고합니다.

나를 미치게 만드는 이유는 스프링 부트가 나에게 맞서 싸우고 시작할 때이 데이터 소스를 인스턴스화해야한다는 것입니다. 나는 Lazy와 Scope 어노테이션을 포함하여 내가 생각할 수있는 모든 것을 시도했다. 세션 범위를 사용하면 시작시 세션이 존재하지 않는다는 오류가 응용 프로그램에서 발생합니다. @Lazy는 전혀 도움이되지 않습니다. 내가 사용하는 어노테이션이 무엇이든, 데이터베이스는 스프링 부트에 의해 시작될 때 인스턴스화되며 본질적으로 전체 애플리케이션을 손상시키는 룩업 키를 찾지 못한다.

다른 문제는 Rest Repository API에 IMO가 실제 데이터 소스를 사용하도록 지정하는 끔찍한 수단이 있다는 것입니다. Spring Boot로 여러 데이터 소스를 가지고 있다면, 런타임 디버깅의 악몽 인 Qualifier annotation을 고글질해야한다.

어떤 조언을 주시면 감사하겠습니다.

해결법

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

    1.문제는 인증 관리자 구성에 있습니다. 모든 샘플 및 가이드는 GlobalAuthenticationConfigurerAdapter에서이를 설정합니다. 그것은 당신의 SimpleEmbeddedSecurityConfiguration의 내부 클래스처럼 보일 것입니다 :

    문제는 인증 관리자 구성에 있습니다. 모든 샘플 및 가이드는 GlobalAuthenticationConfigurerAdapter에서이를 설정합니다. 그것은 당신의 SimpleEmbeddedSecurityConfiguration의 내부 클래스처럼 보일 것입니다 :

    @Configuration
    public static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter
    {
        @Bean(name = Global.AUTHENTICATION_DATA_QUALIFIER + "DataSource")
        public DataSource dataSource()
        {
            return new EmbeddedDatabaseBuilder().setName("authdb").setType(EmbeddedDatabaseType.H2).addScripts("security/schema.sql", "security/data.sql").build();
        }
    
        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception
        {
                auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(passwordEncoder());
        }
    }
    

    GlobalAuthenticationConfigurerAdapter를 사용하지 않으면 @Primary DataSource 빈이 등록되기도 전에 보안 필터를 생성하는 동안 Spring Data REST에 의해 DataSource가 선택되고 전체 JPA 초기화가 일찍 시작된다.

    업데이트 : 인증 관리자가 유일한 문제는 아닙니다. session-scoped @Primary DataSource가 필요하다면, 시작할 때 (Hibernate와 Spring Boot 여러 곳에서) 데이터베이스에 접근하고자하는 모든 것을 꺼야한다. 예:

    spring.datasource.initialize: false
    spring.jpa.hibernate.ddlAuto: none
    spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: false
    spring.jpa.properties.hibernate.dialect: H2
    

    추가 업데이트 : 액츄에이터를 사용하는 경우 시작시 기본 데이터 소스를 사용하여 상태 표시기를 원합니다. 같은 유형의 bean을 알려줌으로써이를 재정의 할 수 있습니다.

    @Bean
    @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
    @Lazy
    public DataSourcePublicMetrics dataSourcePublicMetrics() {
        return new DataSourcePublicMetrics();
    }
    

    추신 GlobalAuthenticationConfigurerAdapter는 Spring Boot 1.2.2에서 필요하지 않을 수도 있지만 1.2.1 또는 1.1.10에 있다고 생각합니다.

  2. from https://stackoverflow.com/questions/28610353/spring-boot-with-session-based-data-source by cc-by-sa and MIT license