Profil default di Spring 3.1

100

Dalam aplikasi saya, saya memiliki kacang yang diberi anotasi @Profile("prod")dan @Profile("demo"). Yang pertama, seperti yang bisa Anda tebak :), digunakan pada bean yang terhubung ke DB produksi dan yang kedua memberi anotasi pada bean yang menggunakan DB palsu ( HashMapatau apapun) - untuk mempercepat pengembangan.

Yang ingin saya miliki adalah profil default ( "prod") yang akan selalu digunakan jika tidak diganti dengan " sesuatu-lain ".

Sempurna untuk memiliki web.xml:

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>prod</param-value>
</context-param>

dan kemudian menimpa ini dengan -Dspring.profiles.active="demo"sehingga saya bisa melakukan:

mvn jetty:run -Dspring.profiles.active="demo". 

Tapi sayangnya ini tidak berhasil. Tahu bagaimana saya bisa mencapai itu? Pengaturan -Dspring.profiles.active="prod"di semua lingkungan saya bukanlah suatu pilihan.

Michał Margiel
sumber

Jawaban:

67

Pengalaman saya adalah menggunakan

@Profile("default")

kacang hanya akan ditambahkan ke konteks jika tidak ada profil lain yang diidentifikasi. Jika Anda memasukkan profil yang berbeda, misalnya -Dspring.profiles.active="demo", profil ini diabaikan.

Paul Philion
sumber
4
Jawaban yang diterima bergantung pada web.xml (dan tidak apa-apa), tetapi jawaban ini berfungsi baik Anda memiliki web.xml atau tidak sehingga lebih bermanfaat secara luas bagi semua orang.
Jay
1
solusi ini jauh lebih bersih
cahen
Apakah ini fitur resmi atau efek samping? Apakah Anda ingin menautkan ke dokumentasi Spring di mana fitur ini dijelaskan?
rustyx
111

Tentukan lingkungan produksi Anda sebagai profil default di web.xml Anda

<context-param>
   <param-name>spring.profiles.default</param-name>
   <param-value>prod</param-value>
</context-param>

dan jika Anda ingin menggunakan profil yang berbeda, teruskan sebagai properti sistem

mvn -Dspring.profiles.active="demo" jetty:run
andih
sumber
3
Tidak, dia mencoba untuk mendefinisikan profil aktif di web.xml dan sebagai properti sistem. Dalam solusi saya, saya mengonfigurasi profil default di web.xml dan menimpa / menentukan profil aktif melalui properti sistem. Jika tidak ada profil aktif yang eksplisit , default akan digunakan.
andih
1
Terima kasih! inilah yang saya inginkan! tidak dapat menemukannya di mana pun: /
Michał Margiel
Satu masalah dengan pendekatan ini: jika Anda mengatur spring.profiles.default=proddi application.properties, maka application-prod.propertiestidak akan dimuat. Ini kontra-intuitif.
gamliela
@gamliela Pendekatan ini tidak menyetel profil default dalam sebuah application.propertiesfile. Untuk mengetahui apa yang application-prod.propertiesharus digunakan, Anda harus mengetahui profilnya. Itulah yang dilakukan pendekatan ini. Ini mendefinisikan profil di luar konteks pegas baik web.xml(default) atau melalui variabel lingkungan (menimpa default).
andih
@andih Ya, saya tahu itu, tapi saya hanya mengatakan itu tidak intuitif dan karena itu bermasalah. Sejak application-default.propertiesdimuat, saya juga berharap itu application-newdefault.propertiesakan dimuat juga. Ini bukan masalah dengan solusi Anda, ini masalah dengan Spring ...
gamliela
6

Saya memiliki masalah yang sama, tetapi saya menggunakan WebApplicationInitializer untuk mengkonfigurasi ServletContext secara terprogram (Servlet 3.0+). Jadi saya melakukan hal berikut:

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        // Create the 'root' Spring application context
        final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        // Default active profiles can be overridden by the environment variable 'SPRING_PROFILES_ACTIVE'
        rootContext.getEnvironment().setDefaultProfiles("prod");
        rootContext.register(AppConfig.class);

        // Manage the lifecycle of the root application context
        sc.addListener(new ContextLoaderListener(rootContext));
    }
}
keren
sumber
5

Anda juga dapat mempertimbangkan untuk menghapus profil PROD, dan menggunakan @Profile ("! Demo")

blacelle
sumber
2
Saya kira ini tidak akan berhasil jika Anda memiliki lebih dari dua profil, bukan?
Potong
3

Tentang pengaturan profil produksi default sudah diposting @andih

Cara termudah untuk mengatur profil default untuk plugin maven jetty, adalah dengan memasukkan elemen di bawah ini ke dalam konfigurasi plugin Anda:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
        <systemProperties>
            <systemProperty>
                <name>spring.profiles.active</name>
                <value>demo</value>
            </systemProperty>
        </systemProperties>
    </configuration>
</plugin>
Jakub Kubrynski
sumber
3

Pegas menyediakan dua properti terpisah saat menentukan profil mana yang aktif:

  • spring.profiles.active

dan

  • spring.profiles.default

Jika spring.profiles.activedisetel, nilainya menentukan profil mana yang aktif. Namun jika spring.profiles.activetidak disetel, Spring akan memeriksanyaspring.profiles.default.

Jika tidak ada spring.profiles.activeatau spring.profiles.defaultdisetel, maka tidak ada profil aktif, dan hanya kacang yang tidak didefinisikan sebagai profil yang dibuat. Kacang apa pun yang tidak menentukan profil adalah milik defaultprofil.

Touhidur Rahaman Khan
sumber
-1

Anda dapat mengatur web.xml Anda sebagai sumber daya yang difilter dan nilai ini diisi oleh maven dari pengaturan profil maven - itulah yang kami lakukan.

di pom filter semua sumber daya (Anda dapat melakukannya jika Anda tidak memiliki tanda $ {} di dalamnya)

<webResources>
    <resource>
        <directory>src/main/webapp</directory>
        <filtering>true</filtering>
    </resource>
</webResources>

di web.xml put

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>${spring.prfile}</param-value>
</context-param>

di pom buat profil maven

<profiles>
    <profile>
        <id>DEFAULT</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profile>prod</spring.profile>
        </properties>
    <profile>
    <profile>
        <id>DEMO</id>
        <properties>
            <spring.profile>demo</spring.profile>
        </properties>
    <profile>
</profiles>

Sekarang Anda bisa menggunakan

mvn jetty:run -P DEMO

atau cukup -P DEMOdengan perintah maven apa saja

Hurda
sumber
1
Saya tidak yakin tapi saya pikir itu tidak akan berhasil. Dermaga IMHO: run tidak akan menjalankan fase di mana sumber daya difilter.
Michał Margiel
dari caurse Anda perlu menjalankan mvn clean compile jetty: run -P DEMO, tetapi dengan kode yang tidak dikompilasi itu berjalan secara otomatis
Hurda
10
Saya memahami bahwa salah satu tujuan utama Profil Spring 3.1 adalah menghasilkan satu file WAR yang siap digunakan di semua lingkungan. Menggunakan profil Maven adalah langkah mundur ke keadaan sebelumnya: di mana pengemasan file WAR diperlukan untuk setiap lingkungan ...
edrabc
@edrabc dia meminta mvn jetty: run - tidak ada file WAR.
Hurda
Setuju @Hurda. Tetapi dia juga meminta untuk menjalankan perintah di berbagai lingkungan: memiliki campuran Profil Maven dan Profil Musim Semi bisa sedikit menyesatkan ...
edrabc