How to externalize Spring Boot application.properties to tomcat/lib folder

前端 未结 3 418
故里飘歌
故里飘歌 2020-11-30 02:02

I need a configuration free, deployable war, myapp1.war that can retrieve the configuration files from the tomcat/lib folder. As I have other web applications coexisting on

相关标签:
3条回答
  • 2020-11-30 02:29

    A solution could be to load application-{profile}.properties as @PropertySource annotations as this question suggests, but then the logging system wont work, as you can see in the documentation.

    The logging system is initialized early in the application lifecycle and as such logging properties will not be found in property files loaded via @PropertySource annotations.

    This means that your logging properties in application-{profiles}.properties like:

    logging.config=classpath:myapp1/logback.xml
    logging.path = /path/to/logs
    logging.file = myapp1.log
    

    will be ignored and the logging system wont work.

    To solve this I have used the SpringApplicationBuilder.properties() method to load properties at the beginning, when the application is configured. There I set the 'spring.config.location' used by Spring Boot to load all the application-{profiles}.properties:

    public class Application extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
            return springApplicationBuilder
                    .sources(Application.class)
                    .properties(getProperties());
        }
    
        public static void main(String[] args) {
    
            SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
                    .sources(Application.class)
                    .properties(getProperties())
                    .run(args);
        }
    
       static Properties getProperties() {
          Properties props = new Properties();
          props.put("spring.config.location", "classpath:myapp1/");
          return props;
       }
    }
    

    Then I have moved the properties files from src/main/resources to src/main/resources/myapp1

    .
    ├src
    | └main
    |   └resources
    |     └myapp1
    |       └application.properties
    |       └application-development.properties
    |       └logback.xml
    └─pom.xml
    

    In the pom.xml I have to set the scope of embedded tomcat libraries as "provided". Also, to exclude all properties files in src/main/resources/myapp1 from the final war and generate a configuration free, deployable war:

        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <packagingExcludes>
                  **/myapp1/
                </packagingExcludes>
            </configuration>
        </plugin>
    

    Then in Tomcat I have

    ├apache-tomcat-7.0.59
     └lib
       ├─myapp1
       |  └application.properties        
       |  └logback.xml
       └─myapp2
         └application.properties
         └logback.xml
    

    Now I can generate the configuration free war and drop it into the apache-tomcat-7.0.59/webapps folder. Properties files will be resolved using the classpath, independently for each webapp:

       apache-tomcat-7.0.59/lib/myapp1
       apache-tomcat-7.0.59/lib/myapp2
       apache-tomcat-7.0.59/lib/myapp3
    
    0 讨论(0)
  • 2020-11-30 02:39

    Daniel Mora gave a good solution but instead of using spring.config.location you can use spring.config.name (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files), so you can have different properties file for different web apps in the same tomcat/lib directory:

        public class Application extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder springApplicationBuilder) {
            return springApplicationBuilder
                    .sources(Application.class)
                    .properties(getProperties());
        }
        public static void main(String[] args) {
    
            SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder(Application.class)
                    .sources(Application.class)
                    .properties(getProperties())
                    .run(args);
        }
    
       static Properties getProperties() {
          Properties props = new Properties();
          props.put("spring.config.name", "myapp1");
          return props;
       }
    }
    

    I think that the lib directory is for third party libraries not for storing configuration properties for your web apps. So I think that a better solution is to add an external folder as additional classpath folder using shared.loader property in conf/catalina.properties:

    shared.loader=${catalina.base}/shared/configurations

    You can put your application properties app1.properties, app2.properties, ecc.. in apache-tomcat-7.0.59/shared/configurations.

    Before finding Daniel Mora solution of overridding configure method of SpringBootServletInitializer my solution was to add a context.xml in src/main/webapp/META-INF with this content:

    <Context>
        <Environment name="spring.config.name" value="myapp1" type="java.lang.String" override="false" description="define the property file for srping boot application"/>
    </Context>
    
    0 讨论(0)
  • 2020-11-30 02:47

    With Spring 4.2 and @Annotation config and tomcat on linux serveur

    In your Application class set the @PropertySource like that :

    @Configuration
    @EnableWebMvc
    @PropertySource(value = { "classpath:application-yourapp.properties"})
    @ComponentScan(basePackages = "com.yourapp")
    public class YourAppWebConfiguration extends WebMvcConfigurerAdapter {
    
        ...
    }
    

    Now you just need to include the property file in your classpath

    In production

    Deploy your .war files ( or anything ) on tomcat, and put your application-yourapp.properties anyway on your production machine. ( for exemple in /opt/applyconfigfolder/application-yourapp.properties" )

    Then in your tomcat ( here tomcat 7 ) open bin\catalina.sh

    You have this line

    # Ensure that any user defined CLASSPATH variables are not used on startup,
    # but allow them to be specified in setenv.sh, in rare case when it is needed.
    CLASSPATH=
    

    Just add the path of the folder which contains application.properties

    CLASSPATH=:/opt/applyconfigfolder
    

    If you have already some classpath define you can add it

    CLASSPATH=:/opt/applyconfigfolder:/yourpath1:/yourpath2:
    

    I haven't try with windows but I think there is no problem

    In Dev ( with eclipse )

    ├src
    | └main
    |   └ ....
    └config
    | └application-yourapp.properties
    

    instead of src/main/resources/application-yourapp.properties

    Now in eclipse add your config folder to classpath, go to "Run Configurations" of your tomcat server ( or equivalent ) and add the folder Config to User Entries

    Ok that's it, your application.properties is out of the application and your project run perfectly in dev environment.

    0 讨论(0)
提交回复
热议问题