Tắt tất cả cấu hình tự động liên quan đến Cơ sở dữ liệu trong Spring Boot


115

Tôi đang sử dụng Spring Boot để phát triển hai ứng dụng, một ứng dụng đóng vai trò là máy chủ và ứng dụng còn lại là ứng dụng khách. Tuy nhiên, cả hai đều là cùng một ứng dụng hoạt động khác nhau dựa trên hồ sơ hoạt động. Tôi đang sử dụng tính năng cấu hình tự động của Spring Boot để cấu hình các ứng dụng của mình.

Tôi muốn tắt tất cả cấu hình tự động liên quan đến cơ sở dữ liệu trên ứng dụng khách, vì nó sẽ không yêu cầu kết nối cơ sở dữ liệu. Ứng dụng không nên cố gắng thiết lập kết nối với cơ sở dữ liệu, cũng như cố gắng sử dụng bất kỳ tính năng Spring Data hoặc Hibernate nào. Việc bật hoặc tắt cấu hình tự động cơ sở dữ liệu phải có điều kiện và dựa trên cấu hình hoạt động của ứng dụng.

Tôi có thể đạt được điều này bằng cách tạo hai tệp application.properties khác nhau cho các cấu hình tương ứng không?

Tôi đã thử thêm cái này vào tệp thuộc tính của mình,

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

Tuy nhiên, ứng dụng vẫn cố gắng kết nối với cơ sở dữ liệu khi khởi động. Những loại trừ đó có đủ để đạt được yêu cầu của tôi không?


Điều này có thể hữu ích.
Rahul Sharma

Bạn có thể tiết lộ mã / cấu hình của bạn không?
luboskrnac

2
Bạn cũng có thể sử dụng cấu hình công cụ xây dựng của mình và chỉ thêm phần phụ thuộc liên quan đến dữ liệu vào một trong các cấu hình của bạn. Nếu gói ứng dụng của bạn bằng cách sử dụng cấu hình khác, vì nó đã không phải là gói khởi động cần trình bày trên classpath, nó sẽ không được tự động cấu hình
Ali Dehghani

Câu trả lời:


99

Cách tôi sẽ làm điều tương tự là:

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

Viết một cái tương tự cho ứng dụng máy chủ (không có loại trừ).

Bước cuối cùng là tắt cấu hình tự động từ lớp khởi động mùa xuân chính:

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

Thay đổi: @SpringBootApplicationthành:

@Configuration 
@ComponentScan

Điều này sẽ thực hiện công việc. Bây giờ, các phần phụ thuộc mà tôi đã loại trừ trong ví dụ này có thể không đầy đủ. Chúng là đủ đối với tôi, nhưng tôi không chắc liệu nó có thể tắt hoàn toàn các thư viện liên quan đến cơ sở dữ liệu hay không. Kiểm tra danh sách dưới đây để chắc chắn:

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

Hy vọng rằng sẽ giúp


5
@SpringBootApplicationexcludetài sản, không cần ClientAppConfiguration.
Abhijit Sarkar

Bạn có thể làm điều đó loại trừ có điều kiện dựa trên cấu hình đang hoạt động mà không sử dụng ClientAppConfiguration không?
patrykos91

1
Đúng. Bạn sẽ loại trừ trong @SpringBootApplication, và sau đó trong gói cụ thể, hãy tạo một @Configurationlớp thực hiện một @Importtrong các lớp có liên quan và phụ thuộc vào @Profilehoặc @Conditional. Bằng cách đó, bạn có thể kiểm tra từng lớp ứng dụng mà không bị rò rỉ autoconfig trên toàn ứng dụng. Muốn kiểm tra DB? Chỉ cần quét gói DB, cấu hình một DB giả và bạn đã sẵn sàng.
Abhijit Sarkar

87

Để tắt tất cả các cấu hình tự động liên quan đến cơ sở dữ liệu và thoát khỏi:

Không thể xác định lớp trình điều khiển cơ sở dữ liệu nhúng cho loại cơ sở dữ liệu NONE

1. Sử dụng chú thích:

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

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

2. Sử dụng Application.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

việc sử dụng Application.properties với Spring Boot 2+ được ưu tiên hơn so với chú thích.
Gustavo Rodrigues

@GustavoRodrigues bạn có thể chia sẻ một số tài liệu để hỗ trợ tuyên bố của mình không? Cảm ơn!
Betlista

27

Có vẻ như bạn vừa quên dấu phẩy để phân cách các lớp. Vì vậy, dựa trên cấu hình của bạn, những điều sau sẽ hoạt động:

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

Ngoài ra, bạn cũng có thể định nghĩa nó như sau:

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

17

Có một cách để loại trừ các lớp cấu hình tự động cụ thể bằng cách sử dụng @SpringBootApplicationchú thích.

@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#excludethuộc tính là một bí danh cho @EnableAutoConfiguration#excludethuộc tính và tôi thấy nó khá tiện dụng và hữu ích.
Tôi đã thêm vào @Import(MyPersistenceConfiguration.class)ví dụ để chứng minh cách bạn có thể áp dụng cấu hình cơ sở dữ liệu tùy chỉnh của mình.


2
Cảm ơn! Đây là câu trả lời hiện đại nhất. Liên kết với nó ở đây: konstructcomputers.blogspot.com/2018/10/...
Joshua Davis

9

Cách ra cho tôi là thêm

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

chú thích cho lớp đang chạy Spring boot (được đánh dấu bằng `@SpringBootApplication).

Cuối cùng, nó trông giống như:

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

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

7

Một cách khác để kiểm soát nó thông qua Hồ sơ là:

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

    }
}

Bạn có thể cho tôi biết làm thế nào để đặt một trình ghi nhật ký bên trong lớp WithoutDB và WithDB để khi tôi khởi động ứng dụng in một số thông tin. Cảm ơn bạn
ankur pramanik

2

Tôi đã gặp vấn đề tương tự ở đây, được giải quyết như thế này:

Chỉ cần thêm một cái khác application-{yourprofile}.ymlmà "yourprofile" có thể là "client".

Trong trường hợp của tôi, tôi chỉ muốn xóa Redis trong hồ sơ Dev, vì vậy tôi đã thêm một application-dev.ymlbên cạnh chính application.ymlvà nó đã hoạt động tốt.

Trong tệp này, tôi đặt:

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

điều này cũng sẽ hoạt động với các tệp thuộc tính.

Tôi thích thực tế là không cần phải thay đổi mã ứng dụng để làm điều đó.


0

Tôi đã gặp lỗi này ngay cả khi tôi đã thực hiện tất cả các giải pháp được đề cập ở trên.

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

Tại một số thời điểm khi tôi tra cứu POM, có sự phụ thuộc này trong đó

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

Và lớp Pojo có các nhập khẩu sau

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

Điều này cho thấy rõ ràng ứng dụng đang mong đợi một nguồn dữ liệu.

Những gì tôi đã làm là tôi đã loại bỏ sự phụ thuộc JPA khỏi pom và thay thế các nhập khẩu cho pojo bằng một lần sau

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

Cuối cùng tôi đã xây dựng THÀNH CÔNG. Kiểm tra xem bạn có thể đã gặp phải vấn đề tương tự


Đây không phải là một giải pháp cho vấn đề được thảo luận. Vấn đề không nằm ở việc loại bỏ tất cả hỗ trợ JPA khỏi ứng dụng mà là bật / tắt nó dựa trên một điều kiện (chẳng hạn như cấu hình Spring) - mà không thay đổi mã hoặc cấu hình dự án Maven. Bạn gặp phải lỗi liên quan đến nguồn dữ liệu vì dường như bạn đã quên xác định và kích hoạt cấu hình Spring sẽ tải cấu hình "no-datasource" thay vì tải các lớp liên quan đến DS / JPA. Các thư viện JPA sẽ vẫn còn trong bản phân phối.
cvnew

1
Tôi không nghĩ rằng bạn đọc hết bài viết của tôi. Trên dòng cuối cùng tôi đang cho thấy nó có thể là vấn đề tương tự nhưng không nói đó là câu trả lời
Tadele Ayelegn

0

Tôi thêm vào myApp.java, sau @SpringBootApplication

@EnableAutoConfiguration (loại trừ = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

Và đã thay đổi

@SpringBootApplication => @Configuration

Vì vậy, tôi có cái này trong lớp chính của mình (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);
}

}

Và làm việc cho tôi! =)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.