spring boot setting up message.properties and errors.properties file in the project structure and reading file to code - spring

I am new to spring boot. I want to add external properties files in project structure . Files are errors.properties, messages.propeties and sql.properties file which contains the all sql queries. I get it where to add it i.e \demo\src\main\resources\errors.properties file. Can Anyone of you give me insight how to read from these files to my java code .

The easiest way would be to leverage what Spring Boot already give you automatically. Anything you put into application.properties (under \demo\src\main\resources) is going to be added to your Environment. I would just take the keys from those three files and create unique entries in application.properites
errors.key1=value1
errors.key2=value2
sql.key1=value1
....
Then you can use the #ConfigurationProperties annotation to map those configurations to a class that encapsulates each type.
#Component
#ConfigurationProperties(prefix="errors")
public class ErrorSettings {
private String key1;
.....
//getter and setters
}
Now you have a Bean of type ErrorSettings that you can inject into any other Bean you declare and just call the getXXX() method of the configuration you want.
Reference doc:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Related

Read YAML file like properties

I am developing a spring boot project, and I need some external configuration. So I am storing that in a file called "config.yml" placed in "src/main/resources" folder.
Now I want the properties in config.yml to be injected in my class. Now if we use SnakeYML or any other parser, we would need to make Java classes to define the schema.
What I want is I can read the yml just like properties using #Value annotation. For e.g.
logging:
class:
name:
location:
I need to access "name" or "location" property using
#Value(${logging.class.name})
private String name;
Is there a way to do that in spring boot?
you don't need to add separate yml. you add custom properties to application.yml or application-{env}.yml
Spring recognise it and you can it via
#Value
Spring environment
Using Spring ConfigurationProperties

Creating a custom FactoryBean in Sprint Boot 2.3/Spring 5

I've got a spring-boot web application that's mostly working; my DataSource is properly configured by an external application.properties file.
Now I want to add properties to that file to help me instantiate and configure two instances of a class in my app. I have a APNsFactory that I currently instantiate manually and configure using JNDI, but I want to get away from JNDI calls:
#Bean
public
APNsFactory
apnsFactory()
throws
javax.naming.NamingException
{
sLogger.info("Configuring APNsFactory");
InitialContext ctx = new InitialContext();
APNsFactory f = new APNsFactory();
f.setProductionKeystorePath((String) ctx.lookup("java:comp/env/apns/prod/keystorePath"));
f.setProductionKeystorePassword((String) ctx.lookup("java:comp/env/apns/prod/keystorePassword"));
f.setDevelopmentKeystorePath((String) ctx.lookup("java:comp/env/apns/dev/keystorePath"));
f.setDevelopmentKeystorePassword((String) ctx.lookup("java:comp/env/apns/dev/keystorePassword"));
return f;
}
When running before in a standalone webapp container, Spring properly called that method and the JNDI context from the container’s <env-entry> tags was available.
I'm trying to update my APNsFactory to be a proper Spring FactoryBean<>, and I’ve given it a couple of #Autowire String variables that I want to be set by Spring Boot from the application.properties file.
For bonus points, I want this to be usable both in Spring Boot and in a standalone container like Tomcat or Resin.
For the life of me, I can't figure out how to get Spring to do this. There are dozens of examples for DataSources and other Beans already implemented by Spring, but none for a completely custom one, using application.properties, in a Spring Boot web environment.
I've seen some examples that use an XML config file, but I'm not sure how to do that with Spring Boot.
I don't think you need a factory bean here.
You already have spring boot that can read application.properties out-of-the-box:
So try the following:
Create key/values in the application.properties file:
myapp.keystore.path=...
myapp.keystore.passwd=...
// the same for other properties
Create ConfigurationProperties class
#ConfigurationProperties(prefix="myapp.keystore")
public class MyAppKeyStoreConfigProperties {
private String path; // the names must match to those defined in the properties file
private String passwd;
... getters, setters
}
In the class marked with #Configuration (the one where you create #Bean public APNsFactory apnsFactory()) do the following:
#Configuration
// Note the following annotation:
#EnableConfigurationProperties(MyAppKeyStoreConfigProperties.class)
public class MyConfiguration {
// Note the injected configuration parameter
#Bean public APNsFactory apnsFactory(MyAppKeyStoreConfigProperties config) {
APNsFactory f = new APNsFactory();
f.setProductionKeystorePath(config.getKeyPath());
and so on
}
}
I've intentionally didn't show the separation between production/dev stuff.
In spring boot you have profiles so that the same artifact (WAR, JAR whatever) can be configured to run with different profile and depending on that the corresponding properties will be read.
Example:
If you're running with prod profile, then in addition to application.properties that will be loaded anyway, you can put these keystore related definitions to application-prod.properties (the suffix matches the profile name) - spring boot will load those automatically. The same goes for dev profile of course.
Now I haven't totally understand the "bonus points" task :) This mechanism is spring boot proprietary way of dealing with configuration. In "standalone" server it should still have a WAR with spring boot inside so it will use this mechanism anyway. Maybe you can clarify more, so that I / our colleagues could provide a better answer

Using properties from application.properties while building bean in spring boot configuration annotated class?

We have properties defined in application.properties, is it appropriate to have the property pulled in a spring-boot #Configuration annotated class to be used for initializing the bean being created. Refer code snippet below
#Configuration
public class MyConfig {
#Value("${a.property.in.application.properties}")
public String aProperty;
#Bean
MyClass myClassInstance() {
return new MyClass(aProperty);
}
}
Simplest example would be creating a datasource instance with url, driver, username, password configured in the application.properties
Is it appropriate?
What could be the possible consequences of continuing to use in this manner?
I'm using this approach for different things like cors configurations. There are probably also disadvantages, but so far it has only had advantages for me. I think it's most times better to have config values outside of the code. That allows you, for example, to use different profiles (local/dev/int/prod). But I would recommend to encrypt things like passwords. I'm using Jasypt.

How to add properties programmatically(just like adding key-value into application.properties)?

I have some common properties that every projects should set, such as
feign.hystrix.enabled=false
feign.httpclient.enabled=true
I don't want to repeatedly add these props in every project so I'm going to create an extra jar file containing #Configruation class. How to add properties in #Configuration class? Thanks!
PropertySources
You may load an application.properties from another jar this way:
#PropertySources({
#PropertySource("classpath:common.properties")
})
#Configuration
public class SomeJavaConfig {
}
You can find the reference in Spring's documentation:
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order:
...
#PropertySource annotations on your #Configuration classes.
Spring-cloud-config
I won't go in all the details, but another option is to use spring-cloud-config to define these properties in a git (using spring-cloud-config-server). Then, have your spring-boot application load the application.properties using spring-cloud-config-client directly from git.
Check this:
https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html
https://spring.io/guides/gs/centralized-configuration/

Spring mvc : Access properties file value in controller without #Value

I have a properties file for messages in my Spring application.I want to access these value directly in controller.How can i do this ?.
Note: I don't want to use #Value annotation to store data in another variable.
You can reference this question and answer regarding accessing files directly within controller.
It is what i used to implement mine.
Accessing multiple property files with #PropertyResource in spring
As M.Deinum suggested already, you should have a MessageSource bean definition if the purpose of the properties file is to externalize messages. A message source is automatically picked by the application context, meaning it is available for injection in every other bean. You can autowire it for example in your controller:
#Autowired
private MessageSource messageSource;
and then use its methods to access any message in any locale

Resources