How to pick spring option arguments at run time in java class - spring-boot

I want to know how to pick spring option arguments like
--server.port , --spring.config.name
in a java class.
Basically I want to know the value of this argument at run time to load some property

You can access them in your application's main() method. A great blog about this topic covers it in detail. Following is how you can do it.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
for(String arg:args) {
System.out.println(arg);
}
SpringApplication.run(Application.class, args);
}
}

Please try using spring org.springframework.core.env.Environment,
public class MyService {
#Autowired
private Environment env;
public String getPropertyValue(String key) {
return env.getProperty(key);
}
}
OR
In application-<env>.propeties (if using spring.profiles)
else application.properties
myapp.property=007
In your class :
#Value("${myapp.property}")
private String myProperty;

Related

How do I get Environment variables in the main method of a spring boot application? [duplicate]

I am trying to get the value of a property
hello.world=Hello World
in MainApp class
#SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
This didn't work as its the main method.
#Value("${hello.world}")
public static String helloWorld;
Maybe its possible to load by
Properties prop = new Properties();
// load a properties file
prop.load(new FileInputStream(filePath));
Is there any other better way to get the properties using Spring in the main method of SpringBoot before SpringApplication.run
ConfigurableApplicationContext ctx =
SpringApplication.run(MainApp.class, args);
String str = ctx.getEnvironment().getProperty("some.prop");
System.out.println("=>>>> " + str);
You have declared the variable helloWorld as static. Hence you need to use Setter Injection and not Field Injection.
Injecting a static non-final field is a bad practice. Hence Spring doesn't allow it. But you can do a workaround like this.
public static String helloWorld;
#Value("${hello.world}")
public void setHelloWorld(String someStr) {
helloWorld = someStr
}
You can access this variable helloWorld at any point in the class, if its any other class. But if you want to do it in the main class. You can access the variable only after this line
SpringApplication.run(MainApp.class, args);)
i.e only after the application has started.
Don't do this. Its better to use CommandLineRunner.
Thanks to this you can have a non static method that Spring Boot will run for you automatically:
#SpringBootApplication
public class SimulatorApplication implements CommandLineRunner {
#Value("${my-value}")
private myValue;
public static void main(String[] args) {
SpringApplication.run(SimulatorApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// here you can access my-value
}
}
#SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(MainApp.class);
springApplication.addListeners(new VersionLogger());
springApplication.run(args);
}
// The VersionLogger Class
public class VersionLogger implements ApplicationListener<ApplicationEnvironmentPreparedEvent>{
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEvent) {
String helloWorld = applicationEvent.getEnvironment().getProperty("hello.world");
}
}
ApplicationEnvironmentPreparedEvent
Event published when a SpringApplication is starting up and the Environment is first available for inspection and modification.
ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
String applicationPropertyVersion=applicationContext.getEnvironment().getProperty("application.property.version");
LOGGER.info("RELEASE CODE VERSION {} and applicationProperty Version {} ", LcoBuildVersion.version,
applicationPropertyVersion);
We can't read values into static fields . Here is the explanation gives a better insight How to assign a value from application.properties to a static variable?

Spring Boot application to read a value from properties file in main method

I am trying to get the value of a property
hello.world=Hello World
in MainApp class
#SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
This didn't work as its the main method.
#Value("${hello.world}")
public static String helloWorld;
Maybe its possible to load by
Properties prop = new Properties();
// load a properties file
prop.load(new FileInputStream(filePath));
Is there any other better way to get the properties using Spring in the main method of SpringBoot before SpringApplication.run
ConfigurableApplicationContext ctx =
SpringApplication.run(MainApp.class, args);
String str = ctx.getEnvironment().getProperty("some.prop");
System.out.println("=>>>> " + str);
You have declared the variable helloWorld as static. Hence you need to use Setter Injection and not Field Injection.
Injecting a static non-final field is a bad practice. Hence Spring doesn't allow it. But you can do a workaround like this.
public static String helloWorld;
#Value("${hello.world}")
public void setHelloWorld(String someStr) {
helloWorld = someStr
}
You can access this variable helloWorld at any point in the class, if its any other class. But if you want to do it in the main class. You can access the variable only after this line
SpringApplication.run(MainApp.class, args);)
i.e only after the application has started.
Don't do this. Its better to use CommandLineRunner.
Thanks to this you can have a non static method that Spring Boot will run for you automatically:
#SpringBootApplication
public class SimulatorApplication implements CommandLineRunner {
#Value("${my-value}")
private myValue;
public static void main(String[] args) {
SpringApplication.run(SimulatorApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// here you can access my-value
}
}
#SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(MainApp.class);
springApplication.addListeners(new VersionLogger());
springApplication.run(args);
}
// The VersionLogger Class
public class VersionLogger implements ApplicationListener<ApplicationEnvironmentPreparedEvent>{
#Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEvent) {
String helloWorld = applicationEvent.getEnvironment().getProperty("hello.world");
}
}
ApplicationEnvironmentPreparedEvent
Event published when a SpringApplication is starting up and the Environment is first available for inspection and modification.
ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
String applicationPropertyVersion=applicationContext.getEnvironment().getProperty("application.property.version");
LOGGER.info("RELEASE CODE VERSION {} and applicationProperty Version {} ", LcoBuildVersion.version,
applicationPropertyVersion);
We can't read values into static fields . Here is the explanation gives a better insight How to assign a value from application.properties to a static variable?

Spring Boot insert sample data into database upon startup

What is the right way for creating test data upon server startup and inserting them into the database (I'm using a JPA/JDBC backed Postgres instance).
Preferably in form of creating Entities and having them persisted through a Repository interface rather than writing plain SQL code. Something like RoR's Rake db:seed helper.
If the framework exposes a hook for doing stuff when all the beans have been injected and the database is ready, that could also work.
You can catch ApplicationReadyEvent then insert demo data, for example:
#Component
public class DemoData {
#Autowired
private final EntityRepository repo;
#EventListener
public void appReady(ApplicationReadyEvent event) {
repo.save(new Entity(...));
}
}
Or you can implement CommandLineRunner or ApplicationRunner, to load demo data when an application is fully started:
#Component
public class DemoData implements CommandLineRunner {
#Autowired
private final EntityRepository repo;
#Override
public void run(String...args) throws Exception {
repo.save(new Entity(...));
}
}
#Component
public class DemoData implements ApplicationRunner {
#Autowired
private final EntityRepository repo;
#Override
public void run(ApplicationArguments args) throws Exception {
repo.save(new Entity(...));
}
}
Or even implement them like a Bean right in your Application (or other 'config') class:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner demoData(EntityRepository repo) {
return args -> {
repo.save(new Entity(...));
}
}
}
From Spring documentation: http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#howto-database-initialization
Initialize a database using Hibernate
A file named import.sql in the root of the classpath will be executed on startup if Hibernate creates the schema from scratch (that is if the ddl-auto property is set to create or create-drop). This can be useful for demos and for testing if you are careful, but probably not something you want to be on the classpath in production. It is a Hibernate feature (nothing to do with Spring).
You can do like this
#SpringBootApplication
public class H2Application {
public static void main(String[] args) {
SpringApplication.run(H2Application.class, args);
}
#Bean
CommandLineRunner init (StudentRepo studentRepo){
return args -> {
List<String> names = Arrays.asList("udara", "sampath");
names.forEach(name -> studentRepo.save(new Student(name)));
};
}
}

How to inject property values into Spring Boot beans

In my spring boot application, i'am trying to inject variable's value from the config file application.properties to my java class and i'm getting a null value.
here is the configuration of my application.properties file:
myapp.username=user#user.com
myapp.password=user
here is where i call the configuration entries:
#Component
public class MyClass{
#Value("${myapp.username}")
public String username;
#Value("${myapp.password}")
public String password;
public static void main(String[] args) {
System.out.println(password);
}
}
I hope there someone how did deal with the same problem, thanks.
you can use this example add bean to your config like this :
#Configuration
#ComponentScan(basePackages = "youpackagebase")
#PropertySource(value = { "classpath:application.properties" })
public class AppConfig {
/*
* PropertySourcesPlaceHolderConfigurer Bean only required for #Value("{}") annotations.
* Remove this bean if you are not using #Value annotations for injecting properties.
*/
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
and in your bean :
#Component
public class NetClient {
#Value("${bigwater.api_config.url.login}")
public String url_login;
Best Regards
You are not even letting the Spring Boot container to boot (initialize) as you are are writing the code directly under main.
You should have an Application class as shown below to launch the Spring boot container properly, look here.
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
As far as my understanding you wanted to execute your code once the container is started, so follow the below steps:
Add the above Application class and then in your NetClient component class add a #Postconstruct method & this method will be called automatically once the bean is ready, refer the code below:
#Component
public class NetClient {
#Value("${bigwater.api_config.url.login}")
public String url_login;
#Value("${bigwater.api_config.url.ws}")
public static String url_ws;
#Value("${bigwater.api_config.username}")
public String username;
#Value("${bigwater.api_config.password}")
public String password;
#Postconstruct
public void init() {
//place all of your main(String[] args) method code here
}
//Add authentification() method here
}

Spring Boot MongoDB REST - Custom Repository Methods

I'm using spring-boot-starter-data-rest and spring-boot-starter-data-mongodb as per the tutorial given here. I'm attempting to create a custom method for a MongoRepository, but having no success.
I've followed the steps given for adding custom behavior to single repositories, but I'm getting a 404 error when I attempt to access the custom method. Hitting the parent endpoint also shows no sign of the method, but I didn't expect it to do that.
Help me, please! What am I doing wrong!?
My code is as follows:
Application.java
#SpringBootApplication
public class Application extends AbstractMongoConfiguration {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ItemRepositoryCustom.java
public interface ItemRepositoryCustom {
void customMethod();
}
ItemRepositoryImpl.java
public class ItemRepositoryImpl {
#Override
public void customMethod() {
...
}
}
ItemRepository.java
#RepositoryRestResource(collectionResourceRel="items", path="items")
public interface ItemRepository extends MongoRepository<Item, String>, ItemRepositoryCustom {
List<Item> findByName(#Param("name") String name);
}
Change your custom implementation class name from ItemRepositoryImpl to ItemRepositoryCustomImpl.
I followed spring documentation here.
Cheers!

Resources