ปิดใช้งานการกำหนดค่าอัตโนมัติที่เกี่ยวข้องกับฐานข้อมูลทั้งหมดใน Spring Boot


115

ฉันใช้ Spring Boot เพื่อพัฒนาแอปพลิเคชั่นสองตัวตัวหนึ่งทำหน้าที่เป็นเซิร์ฟเวอร์และอีกแอปหนึ่งเป็นแอปไคลเอนต์ อย่างไรก็ตามทั้งสองเป็นแอปเดียวกันที่ทำงานแตกต่างกันไปตามโปรไฟล์ที่ใช้งานอยู่ ฉันใช้คุณสมบัติการกำหนดค่าอัตโนมัติของ Spring Boot เพื่อกำหนดค่าแอปพลิเคชันของฉัน

ฉันต้องการปิดการใช้งานฐานข้อมูลทั้งหมดที่เกี่ยวข้องกับการกำหนดค่าอัตโนมัติในแอปไคลเอนต์เนื่องจากไม่จำเป็นต้องเชื่อมต่อฐานข้อมูล แอปพลิเคชันไม่ควรพยายามสร้างการเชื่อมต่อกับฐานข้อมูลหรือพยายามใช้คุณสมบัติ Spring Data หรือ Hibernate การเปิดหรือปิดการกำหนดค่าฐานข้อมูลอัตโนมัติควรเป็นไปตามเงื่อนไขและขึ้นอยู่กับโปรไฟล์ที่ใช้งานอยู่ของแอป

ฉันสามารถทำได้โดยการสร้างไฟล์ application.properties ที่แตกต่างกันสองไฟล์สำหรับโปรไฟล์ที่เกี่ยวข้องหรือไม่

ฉันพยายามเพิ่มสิ่งนี้ลงในไฟล์คุณสมบัติของฉัน

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

แต่แอปพลิเคชันยังคงพยายามเชื่อมต่อกับฐานข้อมูลเมื่อเริ่มต้น การยกเว้นเหล่านั้นเพียงพอสำหรับการบรรลุข้อกำหนดของฉันหรือไม่


สิ่งนี้อาจช่วยได้
Rahul Sharma

คุณสามารถเปิดเผยรหัส / การกำหนดค่าของคุณได้หรือไม่?
luboskrnac

2
คุณยังสามารถใช้โปรไฟล์เครื่องมือสร้างของคุณและเพิ่มการอ้างอิงที่เกี่ยวข้องกับข้อมูลในโปรไฟล์ของคุณเท่านั้น หากแพ็กเกจแอปของคุณโดยใช้โปรไฟล์อื่นเนื่องจากไม่มีแพ็กเกจเริ่มต้นที่จำเป็นในคลาสพา ธ จึงจะไม่ได้รับการกำหนดค่าโดยอัตโนมัติ
Ali Dehghani

คำตอบ:


100

วิธีที่ฉันจะทำสิ่งที่คล้ายกันคือ:

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

เขียนสิ่งที่คล้ายกันสำหรับแอปเซิร์ฟเวอร์ (โดยไม่รวม)

ขั้นตอนสุดท้ายคือการปิดใช้งานการกำหนดค่าอัตโนมัติจากคลาสสปริงบูตหลัก:

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

เปลี่ยน: @SpringBootApplicationเป็น:

@Configuration 
@ComponentScan

นี้ควรจะทำงาน ตอนนี้การอ้างอิงที่ฉันยกเว้นในตัวอย่างอาจไม่สมบูรณ์ เพียงพอสำหรับฉัน แต่ฉันไม่แน่ใจว่าทั้งหมดนี้ปิดการใช้งานไลบรารีที่เกี่ยวข้องกับฐานข้อมูลหรือไม่ ตรวจสอบรายชื่อด้านล่างเพื่อให้แน่ใจว่า:

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

หวังว่าจะช่วยได้


5
@SpringBootApplicationมีคุณสมบัติไม่จำเป็นต้องให้exclude ClientAppConfiguration
Abhijit Sarkar

คุณสามารถทำการยกเว้นแบบมีเงื่อนไขตามโปรไฟล์ที่ใช้งานอยู่โดยไม่ใช้ ClientAppConfiguration ได้หรือไม่?
patrykos91

1
ใช่. คุณจะไม่รวมใน@SpringBootApplicationและจากนั้นในแพคเกจที่เฉพาะเจาะจงสร้าง@Configurationระดับที่ไม่@Importของการเรียนที่เกี่ยวข้องและจะขึ้นอยู่กับหรือ@Profile @Conditionalด้วยวิธีนี้คุณสามารถทดสอบแต่ละเลเยอร์ของแอปพลิเคชันโดยที่ autoconfig ไม่รั่วไหลไปทั่วแอป ต้องการทดสอบ DB ไหม เพียงสแกนแพ็คเกจ DB กำหนดค่าฐานข้อมูลจำลองและคุณก็พร้อมใช้งาน
Abhijit Sarkar

89

สำหรับการปิดใช้งานฐานข้อมูลทั้งหมดที่เกี่ยวข้องกับการกำหนดค่าอัตโนมัติและออกจาก:

ไม่สามารถกำหนดคลาสไดรเวอร์ฐานข้อมูลแบบฝังสำหรับประเภทฐานข้อมูล NONE

1. การใช้คำอธิบายประกอบ:

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

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

2. การใช้ Application.properties:

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

การใช้ Application.properties กับ Spring Boot 2+ เป็นที่นิยมมากกว่าคำอธิบายประกอบ
Gustavo Rodrigues

@GustavoRodrigues คุณสามารถแบ่งปันเอกสารเพื่อสนับสนุนคำชี้แจงของคุณได้หรือไม่? ขอบคุณ!
Betlista

27

ดูเหมือนว่าคุณลืมจุลภาคเพื่อแยกชั้นเรียน ตามการกำหนดค่าของคุณสิ่งต่อไปนี้จะใช้งานได้:

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

หรือคุณสามารถกำหนดได้ดังนี้:

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

มีวิธีการยกเว้นคลาสการกำหนดค่าอัตโนมัติโดยใช้@SpringBootApplicationคำอธิบายประกอบ

@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#excludeแอตทริบิวต์เป็นนามแฝงสำหรับ@EnableAutoConfiguration#excludeแอตทริบิวต์และฉันคิดว่ามันค่อนข้างสะดวกและมีประโยชน์
ฉันเพิ่มลง@Import(MyPersistenceConfiguration.class)ในตัวอย่างเพื่อสาธิตวิธีใช้การกำหนดค่าฐานข้อมูลแบบกำหนดเองของคุณ


2
ขอบคุณ! นี่คือคำตอบที่ทันสมัยที่สุด เชื่อมโยงได้ที่นี่: konstructcomputers.blogspot.com/2018/10/…
Joshua Davis

10

ทางออกสำหรับฉันคือการเพิ่ม

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

คำอธิบายประกอบไปยังคลาสที่รัน Spring boot (มีเครื่องหมาย `@SpringBootApplication)

สุดท้ายดูเหมือนว่า:

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

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

7

อีกวิธีหนึ่งในการควบคุมผ่าน Profiles คือ:

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

    }
}

คุณช่วยบอกฉันได้ไหมว่าจะใส่คนตัดไม้ในคลาส WithoutDB และ WithDB ได้อย่างไรเมื่อฉันเริ่มแอปพลิเคชันพิมพ์ somemessage ขอบคุณ
ankur pramanik

2

ฉันมีปัญหาเดียวกันที่นี่แก้ไขดังนี้:

เพียงเพิ่มรายการอื่นapplication-{yourprofile}.ymlโดยที่ "yourprofile" อาจเป็น "ไคลเอ็นต์"

ในกรณีของฉันฉันแค่ต้องการลบ Redis ในโปรไฟล์ Dev ดังนั้นฉันจึงเพิ่มapplication-dev.ymlถัดจากหลักapplication.ymlและมันก็ทำงานได้

ในไฟล์นี้ฉันใส่:

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

สิ่งนี้ควรทำงานกับไฟล์คุณสมบัติเช่นกัน

ฉันชอบความจริงที่ว่าไม่จำเป็นต้องเปลี่ยนรหัสแอปพลิเคชันเพื่อทำเช่นนั้น


0

ฉันได้รับข้อผิดพลาดนี้แม้ว่าฉันจะแก้ปัญหาทั้งหมดที่กล่าวมาแล้วก็ตาม

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

ในบางจุดเมื่อฉันค้นหา POM มีการพึ่งพานี้อยู่ในนั้น

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

และคลาส Pojo มีการนำเข้าดังต่อไปนี้

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

ซึ่งแสดงให้เห็นอย่างชัดเจนว่าแอปพลิเคชันกำลังคาดหวังแหล่งข้อมูล

สิ่งที่ฉันทำคือฉันลบการพึ่งพา JPA ออกจาก pom และแทนที่การนำเข้าสำหรับ pojo ด้วยสิ่งต่อไปนี้หนึ่งครั้ง

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

ในที่สุดฉันก็ได้งานสร้างที่ประสบความสำเร็จ ตรวจสอบว่าคุณอาจประสบปัญหาเดียวกัน


นี่ไม่ใช่วิธีแก้ปัญหาที่กล่าวถึง ปัญหาไม่ได้เกี่ยวกับการลบการสนับสนุน JPA ออกจากแอปพลิเคชันทั้งหมด แต่เป็นการเปิด / ปิดการใช้งานตามเงื่อนไข (เช่นโปรไฟล์ Spring) - โดยไม่ต้องเปลี่ยนรหัสหรือการกำหนดค่าโครงการ Maven คุณได้รับข้อผิดพลาดที่เกี่ยวข้องกับแหล่งข้อมูลเนื่องจากคุณลืมกำหนดและเปิดใช้งานโปรไฟล์ Spring ที่จะโหลดการกำหนดค่า "no-datasource" แทนที่จะโหลดคลาสที่เกี่ยวข้องกับ DS / JPA ห้องสมุด JPA ควรยังคงอยู่ในการแจกจ่าย
cvnew

1
ฉันไม่คิดว่าคุณจะอ่านโพสต์ของฉันจนหมด ในบรรทัดสุดท้ายฉันขอแนะนำว่าอาจเป็นปัญหาที่คล้ายกัน แต่ไม่ได้บอกว่านั่นคือคำตอบ
Tadele Ayelegn

0

ฉันเพิ่ม myApp.java หลัง @SpringBootApplication

@EnableAutoConfiguration (ไม่รวม = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

และเปลี่ยนไป

@SpringBootApplication => @ การกำหนดค่า

ดังนั้นฉันมีสิ่งนี้ในคลาสหลักของฉัน (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);
}

}

และทำงานให้ฉัน! =)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.