복붙노트

[SPRING] 스프링 부트 애플리케이션 시작시 H2 TCP 서버를 시작하는 방법은 무엇입니까?

SPRING

스프링 부트 애플리케이션 시작시 H2 TCP 서버를 시작하는 방법은 무엇입니까?

SpringBootServletInitializer main 메소드에 다음 줄을 추가하여 Spring 부팅 응용 프로그램으로 응용 프로그램을 실행할 때 H2 TCP 서버 (파일의 데이터베이스)를 시작할 수 있습니다.

@SpringBootApplication
public class NatiaApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        Server.createTcpServer().start();
        SpringApplication.run(NatiaApplication.class, args);
    }
}

하지만 Tomcat에서 WAR 파일을 실행하면 main 메소드가 호출되지 않기 때문에 작동하지 않습니다. 콩이 초기화되기 전에 응용 프로그램 시작시 H2 TCP 서버를 시작하는 더 나은 보편적 인 방법이 있습니까? 나는 Flyway (autoconfig)를 사용하고 서버가 실행 중이 아니기 때문에 "Connection refused : connect"에서 실패합니다. 고맙습니다.

해결법

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

    1.이 솔루션은 나를 위해 작동합니다. 이 응용 프로그램이 Spring Boot 응용 프로그램으로 실행되고 Tomcat에서 실행되는 경우 H2 서버를 시작합니다. Flyway bean이 이전에 작성되어 "Connection refused"에서 실패했기 때문에 bean으로 H2 서버를 작성하지 않았습니다.

    이 솔루션은 나를 위해 작동합니다. 이 응용 프로그램이 Spring Boot 응용 프로그램으로 실행되고 Tomcat에서 실행되는 경우 H2 서버를 시작합니다. Flyway bean이 이전에 작성되어 "Connection refused"에서 실패했기 때문에 bean으로 H2 서버를 작성하지 않았습니다.

    @SpringBootApplication
    @Log
    public class NatiaApplication extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            startH2Server();
            SpringApplication.run(NatiaApplication.class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            startH2Server();
            return application.sources(NatiaApplication.class);
        }
    
        private static void startH2Server() {
            try {
                Server h2Server = Server.createTcpServer().start();
                if (h2Server.isRunning(true)) {
                    log.info("H2 server was started and is running.");
                } else {
                    throw new RuntimeException("Could not start H2 server.");
                }
            } catch (SQLException e) {
                throw new RuntimeException("Failed to start H2 server: ", e);
            }
        }
    }
    
  2. ==============================

    2.WAR 패키징의 경우 다음을 수행 할 수 있습니다.

    WAR 패키징의 경우 다음을 수행 할 수 있습니다.

    public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return null;
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            Server.createTcpServer().start();
            return new Class[] { NatiaApplication.class };
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[] { "/" };
        }
    
    }
    
  3. ==============================

    3.네, 문서에서 직접, 당신은 콩 참조를 사용할 수 있습니다 :

    네, 문서에서 직접, 당신은 콩 참조를 사용할 수 있습니다 :

    <bean id = "org.h2.tools.Server"
            class="org.h2.tools.Server"
            factory-method="createTcpServer"
            init-method="start"
            destroy-method="stop">
    <constructor-arg value="-tcp,-tcpAllowOthers,-tcpPort,8043" />
    

    또한 자동 시작 / 중지하는 서블릿 리스너 옵션이 있습니다.

    그 질문에 대한 답변,하지만 당신이 아마 봄 부팅 응용 프로그램과 함께 배포하는 경우 대신 임베디드 모드를 사용해야한다고 생각합니다. 이것은 훨씬 빠르고 자원이 가볍습니다. 단순히 올바른 URL을 지정하면 데이터베이스가 시작됩니다.

    jdbc:h2:/usr/share/myDbFolder
    

    (치트 시트에서 곧바로).

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

    4.다음과 같이 할 수 있습니다.

    다음과 같이 할 수 있습니다.

    @Configuration
    public class H2ServerConfiguration {
    
      @Value("${db.port}")
      private String h2TcpPort;
    
      /**
       * TCP connection to connect with SQL clients to the embedded h2 database.
       *
       * @see Server
       * @throws SQLException if something went wrong during startup the server.
       * @return h2 db Server
       */
       @Bean
        public Server server() throws SQLException {
            return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", h2TcpPort).start();
       }
    
       /**
        * @return FlywayMigrationStrategy the strategy for migration.
        */
        @Bean
        @DependsOn("server")
        public FlywayMigrationStrategy flywayMigrationStrategy() {
            return Flyway::migrate;
        }
    }
    
  5. ==============================

    5.다른 답변에는 고려되지 않은 경고가 있습니다. 알고 있어야 할 것은 서버를 시작하는 것이 DataSource 빈에 일시적으로 의존한다는 것입니다. 이는 DataSource가 Bean 관계가 아닌 네트워크 연결 만 필요로하기 때.입니다.

    다른 답변에는 고려되지 않은 경고가 있습니다. 알고 있어야 할 것은 서버를 시작하는 것이 DataSource 빈에 일시적으로 의존한다는 것입니다. 이는 DataSource가 Bean 관계가 아닌 네트워크 연결 만 필요로하기 때.입니다.

    이것이 원인 인 문제는 스프링 부트가 DataSource를 만들기 전에 시작해야하는 h2 데이터베이스에 대해 알지 못하기 때문에 애플리케이션 시작시 연결 예외로 끝날 수 있다는 것입니다.

    스프링 프레임 워크를 사용하면 DB 서버 시작을 루트 구성에두고 데이터베이스를 자식으로두면 문제가되지 않습니다. AFAIK 스프링 부트에는 단 하나의 상황 만 있습니다.

    이 문제를 해결하려면 데이터 원본에 대한 선택적 종속성을 만드는 것이 좋습니다. Optional을 사용하는 이유는 프로덕션 DB가있는 서버 (구성 매개 변수)를 항상 시작하지 않을 수도 있기 때문입니다.

    @Bean(destroyMethod = "close")
    public DataSource dataSource(Optional<Server> h2Server) throws PropertyVetoException {
        HikariDataSource ds = new HikariDataSource();
        ds.setDriverClassName(env.getProperty("db.driver"));
        ds.setJdbcUrl(env.getProperty("db.url"));
        ds.setUsername(env.getProperty("db.user"));
        ds.setPassword(env.getProperty("db.pass"));
        return ds;
    }
    
  6. from https://stackoverflow.com/questions/37068808/how-to-start-h2-tcp-server-on-spring-boot-application-startup by cc-by-sa and MIT license