2016-05-06 40 views
5

Ben SpringBootServletInitializer ana yöntem haline aşağıdaki satırı ekleyerek Bahar Boot uygulaması olarak çalıştırırken H2 TCP sunucusunu (bir dosyada veritabanı) başlatmak mümkün değilim:Spring Boot uygulaması başlatılırken H2 TCP sunucusu nasıl başlatılır?

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

Ama WAR dosyasını çalıştırırsanız Tomcat çalışmıyor çünkü ana yöntem çağrılmıyor. Fasulye başlatılmadan önce H2 TCP sunucusunun uygulama başlangıcında nasıl başlatılmasının daha iyi bir evrensel yolu var mı? Flyway'i (autoconfig) kullanıyorum ve sunucunun çalışmadığı için "Bağlantı reddedildi: bağlan" bağlantısında başarısız oluyor. Teşekkür ederim.

cevap

5

Bu çözüm benim için çalışır. Uygulama, Spring Boot uygulaması olarak çalışıyorsa ve ayrıca Tomcat üzerinde çalışıyorsa, H2 sunucusunu başlatır. Flyway fasülyesi daha önce yaratıldığından ve "Connection reddedildi" de başarısız olduğundan, H2 sunucusunun fasulye olarak oluşturulması işe yaramadı.

@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

SAVAŞ paketleme için bunu yapabilirsiniz:

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[] { "/" }; 
    } 

} 
2

Evet, straight from the documentation, bir fasulye başvuru kullanabilirsiniz:

<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" /> 

ayrıca servlet listener option that auto-starts/stops it.

var That sorunuzu cevaplıyor, ama muhtemelen e Bahar önyükleme uygulamanızla birlikte dağıtıyorsa mbedded modu. Bu, kaynaklarda daha hızlı ve daha açık. Sadece doğru URL'yi belirtmek ve veritabanı başlayacak:

jdbc:h2:/usr/share/myDbFolder 

(straight out of the cheat sheet).

+0

Ne yazık ki bu benim için çalışmaz. Otomatik yapılandırılmış Flyway fasulyesinin H2 sunucu çekirdeğinden önce oluşturulduğu ve bağlantı reddedildiğinde başarısız olduğu görülüyor. Herhangi bir fasülyeden önce H2 sunucusunun çalıştırılmasına ihtiyacım var. – Vojtech

+0

@Vojtech İlk önce fasulyelerin diğer fasulyelere nasıl dayanacağını öğrenmek için, bakınız: http: // stackoverflow.com/sorular/7868335/yay makyaj emin-a-belli-fasulye-İlk degeri-ilk – BobMcGee

0

Böyle yapabilirsiniz:

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

diğer cevaplar dikkate edilmemiş bir uyarı var. Farkında olmanız gereken, bir sunucu başlatmanın DataSource fasulyenizde geçici bir bağımlılık olmasıdır. Bunun nedeni, DataSource'un yalnızca bir ağ bağlantısına, fasulye ilişkisine değil.

bu neden sorun h2 veritabanı uygulama başlangıçta bir bağlantı haricinde bitebileceğini böylece DataSource oluşturmadan önce kadar ateş edilmesi gerek bilmiyor ki yay çizme olduğunu. Çocukken veritabanı ile RootConfig DB sunucusu başlangıç ​​dediği gibi yay temeli ile

bu bir sorun değildir. AFAIK bahar botu ile sadece tek bir içerik var.

ne yapabilirim veri kaynağına bir Optional<Server> bağımlılık yaratmak olduğunu Bundan kaçınmak için. Optional'un nedeni, her zaman için üretim DB'niz olabilecek sunucuyu (yapılandırma parametresi) başlatmamış olabilirsiniz.

@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; 
} 
İlgili konular