Spring : Add properties file externally

how to read external properties file in spring boot example
spring boot add external folder to classpath
spring batch external properties file
how to read external yaml file in spring boot
spring boot external resources
spring boot application.properties example
how to add external configuration in spring boot
spring tomcat external properties file

I am working on a Spring-MVC application in which we are preparing to setup application on different servers. As each server can have it's own database related configuration, we are hoping to use an external properties file(outside the war file) which can be read while project is starting. How do I go about this approach? For making it work, I have already moved application initialization code to Java, this way, static XML reading which we had before won't be required. But, we are unsure how to create and add a properties file dynamically which atleast has these 3 values(JDBC URL containing DB name, username, password). All tables, other data will be created automatically.

Here is the class where app is initialized :

WebConfig.java :

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.ourapp.spring"})
@EnableTransactionManagement
@EnableCaching
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    @Bean
    public ReloadableResourceBundleMessageSource messageSource(){
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("../resources/locale/messages.properties");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocaleChangeInterceptor localeInterceptor(){
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        return interceptor;
    }

    @Bean
    public MappingJackson2HttpMessageConverter converter() {
        return new MappingJackson2HttpMessageConverter();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/img/**").addResourceLocations("/img/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    }

    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("../webapp/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Bean
    public DoNotTruncateMyUrls doNotTruncate(){
       return new DoNotTruncateMyUrls();
    }

    @Bean
    public MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Bean
    @Qualifier("primary_tx")
    public HibernateTransactionManager getPrimaryTransactionManager() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(sessionFactory().getObject());
        return txName;
    }

    @Bean
    @Qualifier("extended_tx")
    public HibernateTransactionManager txName() throws IOException {
        HibernateTransactionManager txName= new HibernateTransactionManager();
        txName.setSessionFactory(getExtendedSessionFactory().getObject());
        return txName;
    }

    @Bean
    @Qualifier("sessionFactory_origin")
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(new DataSourceConfig().primaryDataSource());
        sessionFactory.setPackagesToScan("com.ourapp.spring");
        return sessionFactory;
    }

    @Bean
    @Qualifier("sessionFactory_extended")
    public LocalSessionFactoryBean getExtendedSessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(new DataSourceConfig_Extended().secondaryDataSource());
        sessionFactory.setPackagesToScan("com.ourapp.spring");
        return sessionFactory;
    }

}

Thank you. :-)

Probably what you are looking for is Profiles( @Profile or @Conditional )

Step1: Create a profile. The following is the example for prod profile. Similarly, you can create one for dev and qa

import javax.activation.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jndi.JndiObjectFactoryBean;

@Configuration
@Profile("prod")
@PropertySource("classpath:/com/<SomePath>/app.properties")
public class ProductionProfileConfig {

    @Autowired Environment env;

    @Bean
    public DataSource dataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName(env.getProperty("dbName"));
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) jndiObjectFactoryBean.getObject();
    }
}

Step2 Activate profiles

Spring honors two separate properties when determining which profiles are active: spring.profiles.active and spring.profiles.default. If spring.profiles.active is set, then its value determines which profiles are active. But if spring .profiles.active isn’t set, then Spring looks to spring.profiles.default. If neither spring.profiles.active nor spring.profiles.default is set, then there are no active profiles, and only those beans that aren’t defined as being in a profile are created

UPDATE

Use PropertyConfigurator.configure(Loader.getResource(<your-file-path>)); if the file is located outside the packaged war. Later you can simply inject values using @Value or SPel

How to Read Properties File in Spring Framework, is to create a new file under the src/main/resources directory. Using external properties files The answer lies in the Spring Boot Docs, I'll try to break it down for you. First of all, no you should not use @PropertySource when working with Yaml configuration, as mentioned here under the Yaml shortcomings :

Write a config manager, which will create configuration objects based on the name of properties file. For example,

Configuration config = ConfigurationManager.getConfig("dbConfig");

so, now your config object will contain all properties related to db. When you instantiate config object read all properties into this object.

Let's say your properties file contains following fields:

user.name = "Tom" user.password = "pass"

Next time when you need "user.name", you would just do config.getString("user.name")

Spring Boot application.properties file, You can use properties files, YAML files, environment variables and command-​line e.g. --server.port=9000 ) to a property and add it to the Spring Environment . If you don't like application.properties as the configuration file name you can switch particularly well with the SpringApplication external YAML configuration: By convention, Spring Boot looks for an externalized configuration file – application.properties or application.yml – in 4 predetermined locations in the following order of precedence: A /config subdirectory of the current directory. The current directory. A classpath /config package. The classpath root.

You can do this using PropertySourcesPlaceholderConfigurer

Create a bean like this

@Bean
public static PropertySourcesPlaceholderConfigurer devPropertyPlaceholderConfigurer() throws IOException {
   PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
   configurer.setLocations(new PathMatchingResourcePatternResolver().getResources("file:pathtToFile"));
   configurer.setIgnoreUnresolvablePlaceholders(true);
   return configurer;
}

For example if you write file:/tmp/dev/*.properties . It will load all the properties file under /tmp/dev.

If you want to customize it based on differnt environment(dev, testing, production). then you can use @Profile and create multiple beans.

@Bean
@Profile("dev")
public static PropertySourcesPlaceholderConfigurer devPropertyPlaceholderConfigurer() throws IOException {
   ..... // give dev properties file path
}


@Bean
@Profile("testing")
public static PropertySourcesPlaceholderConfigurer testPropertyPlaceholderConfigurer() throws IOException {
.....// give test properties file path
}

@Bean
@Profile("prod")
public static PropertySourcesPlaceholderConfigurer prodPropertyPlaceholderConfigurer() throws IOException {
.....// give prod properties file path
}

21. Externalized Configuration, Probably what you are looking for is Profiles( @Profile or @Conditional ). Step1: Create a profile. The following is the example for prod profile. Spring Boot allows you to specify durations with the following units in the application.properties files - ns for nanoseconds; us for microseconds; ms for milliseconds; s for seconds; m for minutes; h for hours; d for days ; The default unit is milliseconds. So if you don’t specify any unit in the properties file, It will be considered as milliseconds.

Spring : Add properties file externally, By default, Spring Boot look for externalized default property file application.​properties into given below predetermined locations: -- In the  Hi, In this blog we'll learn how we can inject configuration properties in a springBoot application and what are the benefits of spring boot over spring while injecting configuration properties. There are two ways to inject our configuration properties:- 1.

How to load external property files into Spring Boot application , We will how it provides a typesafe property configuration as well as how to add validations to Duration: 8:31 Posted: Jan 23, 2019 The foo.properties file should be placed under /src/main/resources so that it will be available on the classpath at runtime. In case multiple <property-placeholder> elements are present in the Spring context, there are a few recommended best practices: the order attribute needs to be specified to fix

Spring Boot: Working With External Property Files and Configuration , When we start a new spring boot application we get the file application.properties under the resources directory. This file can be use for configure all kind of stuff,  Spring @PropertySource. Spring @PropertySource annotation is used to provide properties file to Spring Environment. This annotation is used with @Configuration classes. Spring PropertySource annotation is repeatable, means you can have multiple PropertySource on a Configuration class.

Comments
  • are you using spring boot? If so you can use config server
  • @pvpkiran : No, Unfortunately I am using spring-mvc.
  • Where will this file be located? On jetty especially this is a problem as Jetty unpacks the war in /tmp within some randomly named folder.
  • That's how you place it on classpath. If the file is inside the src folder directly use /file.properties
  • I am looking to place it outside the WAR file. Any way I can do it same way by placing it externally somewhere
  • Use PropertyConfigurator.configure(Loader.getResource(<your-file-path>)); Later you can simply inject values using @Value or SPel
  • Where will this db.config located?
  • better approach would be to create a separate web service which would serve your properties only
  • Even if a new service is created, I would have to load the database values during startup. How would a separate webservice change it