Wyłącz całą automatyczną konfigurację związaną z bazą danych w Spring Boot

115

Używam Spring Boot do tworzenia dwóch aplikacji, jedna służy jako serwer, a druga jest aplikacją kliencką. Jednak obie są tą samą aplikacją, która działa inaczej w zależności od aktywnego profilu. Do konfigurowania aplikacji używam funkcji automatycznej konfiguracji Spring Boot.

Chcę wyłączyć całą automatyczną konfigurację związaną z bazą danych w aplikacji klienta, ponieważ nie będzie to wymagać połączenia z bazą danych. Aplikacja nie powinna próbować nawiązać połączenia z bazą danych ani próbować korzystać z żadnych funkcji Spring Data lub Hibernate. Włączanie lub wyłączanie automatycznej konfiguracji bazy danych powinno być warunkowe i oparte na aktywnym profilu aplikacji.

Czy mogę to osiągnąć, tworząc dwa różne pliki application.properties dla odpowiednich profili?

Próbowałem dodać to do mojego pliku właściwości,

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration\
  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration\
  org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration

Jednak aplikacja nadal próbuje połączyć się z bazą danych podczas uruchamiania. Czy te wyłączenia są wystarczające, aby spełnić moje wymagania?

yuva
źródło
To może pomóc.
Rahul Sharma
Czy możesz ujawnić swój kod / konfigurację?
luboskrnac
2
Możesz również użyć profili narzędzia kompilacji i dodać zależności związane z danymi tylko w jednym ze swoich profili. Jeśli spakujesz swoją aplikację przy użyciu innego profilu, ponieważ nie ma wymaganych pakietów startowych obecnych na ścieżce klas, nie zostanie automatycznie skonfigurowana
Ali Dehghani

Odpowiedzi:

100

Sposób, w jaki zrobiłbym coś podobnego, to:

@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@Profile ("client_app_profile_name")
public class ClientAppConfiguration {
    //it can be left blank
}

Napisz podobny dla aplikacji serwera (bez wykluczeń).

Ostatnim krokiem jest wyłączenie automatycznej konfiguracji z klasy rozruchowej sprężyny głównej:

@SpringBootApplication
public class SomeApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SomeApplication.class);
    }

    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SomeApplication.class);
    }
}

Zmień: @SpringBootApplicationna:

@Configuration 
@ComponentScan

To powinno wystarczyć. Teraz zależności, które wykluczyłem w przykładzie, mogą być niekompletne. Były dla mnie wystarczające, ale nie jestem pewien, czy to wszystko, aby całkowicie wyłączyć biblioteki związane z bazą danych. Sprawdź poniższą listę, aby się upewnić:

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#auto-configuration-classes

Mam nadzieję, że to pomoże

patrykos91
źródło
5
@SpringBootApplicationma excludewłasność, nie ma takiej potrzeby ClientAppConfiguration.
Abhijit Sarkar
Czy możesz to zrobić, aby wykluczyć warunkowe na podstawie aktywnego profilu bez korzystania z ClientAppConfiguration?
patrykos91
1
Tak. Wykluczyłbyś w @SpringBootApplication, a następnie w określonym pakiecie utworzyłbyś @Configurationklasę, która wykonuje an @Importz odpowiednich klas i jest zależna od @Profilelub @Conditional. W ten sposób możesz przetestować każdą warstwę aplikacji bez wycieku autoconfigu po całej aplikacji. Chcesz przetestować DB? Wystarczy zeskanować pakiet DB, skonfigurować próbną bazę danych i gotowe.
Abhijit Sarkar
89

Aby wyłączyć całą autokonfigurację związaną z bazą danych i wyjść z:

Nie można określić klasy sterownika wbudowanej bazy danych dla typu bazy danych BRAK

1. Korzystanie z adnotacji:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Application {

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

2. Korzystanie z Application.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
Jorge López
źródło
użycie Application.properties w Spring Boot 2+ jest lepsze niż w przypadku adnotacji.
Gustavo Rodrigues
@GustavoRodrigues czy możesz udostępnić jakąś dokumentację na poparcie swojego oświadczenia? Dzięki!
Betlista
27

Wygląda na to, że zapomniałeś o przecinku, aby oddzielić klasy. Zatem w oparciu o twoją konfigurację zadziała:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
    org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration

Alternatywnie możesz również zdefiniować to w następujący sposób:

spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[2]=org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
spring.autoconfigure.exclude[3]=org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration
Julien May
źródło
17

Istnieje sposób na wykluczenie określonych klas automatycznej konfiguracji za pomocą @SpringBootApplicationadnotacji.

@Import(MyPersistenceConfiguration.class)
@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class, 
        DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class})
public class MySpringBootApplication {         
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}

@SpringBootApplication#excludeatrybut jest aliasem dla @EnableAutoConfiguration#excludeatrybutu i uważam, że jest raczej przydatny i przydatny.
Dodałem @Import(MyPersistenceConfiguration.class)do przykładu, aby zademonstrować, jak można zastosować niestandardową konfigurację bazy danych.

naXa
źródło
2
Dzięki! To najnowocześniejsza odpowiedź. Powiązane z tym tutaj: konstructcomputers.blogspot.com/2018/10/…
Joshua Davis
10

Wyjściem dla mnie było dodanie

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

adnotacja do klasy uruchamiającej Spring Boot (oznaczona jako `@SpringBootApplication).

Wreszcie wygląda to tak:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Application{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
 }
ryzhman
źródło
7

Innym sposobem kontrolowania tego za pomocą profili jest:

// note: no @SpringApplication annotation here
@Import(DatabaseConfig.class)
public class Application {

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

@Configuration
@Import({DatabaseConfig.WithDB.class, DatabaseConfig.WithoutDB.class})
public class DatabaseConfig {

    @Profile("!db")
    @EnableAutoConfiguration(
            exclude = {DataSourceAutoConfiguration.class,   DataSourceTransactionManagerAutoConfiguration.class,
                HibernateJpaAutoConfiguration.class})
    static class WithoutDB {

    }

    @Profile("db")
    @EnableAutoConfiguration
    static class WithDB {

    }
}
Sztylet
źródło
Czy możesz mi powiedzieć, jak umieścić rejestrator w klasie WithoutDB i WithDB, aby po uruchomieniu aplikacji wydrukować jakąś wiadomość. Dziękuję
ankur pramanik
2

Miałem tutaj ten sam problem, rozwiązany w ten sposób:

Po prostu dodaj kolejny application-{yourprofile}.yml gdzie „twój profil” może oznaczać „klient”.

W moim przypadku chciałem tylko usunąć Redis w profilu dewelopera, więc dodałem application-dev.ymlobok głównego application.ymli wykonałem zadanie.

W tym pliku umieściłem:

spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration

powinno to działać również z plikami właściwości.

Podoba mi się fakt, że nie ma do tego potrzeby zmiany kodu aplikacji.

Sylvain
źródło
0

Otrzymałem ten błąd, nawet jeśli wykonałem wszystkie powyższe rozwiązania.

 by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfig ...

W pewnym momencie, kiedy sprawdzam POM, była w nim taka zależność

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

A klasa Pojo miała następujący import

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;

Co wyraźnie pokazuje, że aplikacja oczekiwała źródła danych.

Co zrobiłem, to usunąłem zależność JPA z pom i zastąpiłem import dla pojo następującym raz

import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document;

W końcu uzyskałem UDANA kompilację. Sprawdź, czy możesz napotkać ten sam problem

Tadele Ayelegn
źródło
To nie jest rozwiązanie omawianego problemu. Problem nie polega na całkowitym usunięciu obsługi JPA z aplikacji, ale raczej na włączeniu / wyłączeniu jej na podstawie warunku (takiego jak profil Spring) - bez zmiany kodu lub konfiguracji projektu Maven. Otrzymujesz błąd związany ze źródłem danych, ponieważ najwyraźniej zapomniałeś zdefiniować i aktywować profil Spring, który ładowałby konfigurację „bez źródła danych” zamiast ładować klasy związane z DS / JPA. Biblioteki JPA powinny nadal pozostać w dystrybucji.
cvnew
1
Myślę, że nie przeczytałeś mojego posta w całości. W ostatnim wierszu sugeruję, że może to być podobny problem, ale nie mówię, że to jest odpowiedź
Tadele Ayelegn
0

Dodaję w myApp.java, po @SpringBootApplication

@EnableAutoConfiguration (exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

I zmienił się

@SpringBootApplication => @Configuration

Mam to w mojej głównej klasie (myApp.java)

package br.com.company.project.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class SomeApplication {

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

}

I pracuj dla mnie! =)

Cássia Chagas
źródło