Hello i am beginner in JAVA Spring Boot.
I can't get value from aplication.yml or get from service(JpaRepository) in singleton class
#Component
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class AuthProviderService {
#Value("${test.value}")
private String testvalue;
#Autowired
private ProductService productService;
}
Spring boot is loading properties in particular way. Please check for spelling mistake in filename (application.yaml)
14.Application properties outside of your packaged jar (application.properties and YAML variants).
15.Application properties packaged inside your jar (application.properties and YAML variants).
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Also, please consider encapsulating you're configuration to #ConfigurationProperties
Related
I got class:
#WebServiceClient(name = "${service.name}", targetNamespace = "${service.namespace}", wsdlLocation = "${service.wsdlLocation}")
public class ExampleService extends Service {
#Value("${service.wsdlLocation}")
private static String wsdlLocation;
}
It is a part of the mvn project which I compile and use from my local maven repo as a dependency to my other spring-boot app, which have configuration yml:
service:
name: name
namespace: namespace
wsdlLocation: wsdlLocation
Is there a way that this ExampleService class will use configuration of the "parent" project?
EDIT:
Two answers appearred, but I felt I did not ask question clearly. What I want to do now is to use class ExampleService in my "parent" project and make it see configuration from that parent project. So far when for example I write in parent project code like:
ExampleService exampleService = new ExampleService();
System.out.println(exampleService.getWsdlLocation());
Null is printed. So I'm looking for some solution to that.
EDIT 2:
Here are my classes.
Parent project:
package com.example.kris.parentservice;
import com.example.kris.childservice.ExampleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/example")
public class ExampleController {
// #Autowired
private ExampleService exampleService;
#Value(value = "${service.wsdlLocation}")
private String wsdlLocation;
#GetMapping(value = "/example")
public void example() {
exampleService = new ExampleService();
System.out.println("ExampleService field: " + exampleService.getWsdlLocation());
System.out.println("#Value: " + wsdlLocation);
}
}
Child project:
package com.example.kris.childservice;
import org.springframework.beans.factory.annotation.Value;
public class ExampleService {
#Value("${service.wsdlLocation}")
private String wsdlLocation;
public String getWsdlLocation() {
return wsdlLocation;
}
}
And output after running parent controller:
ExampleService field: null
#Value:test.wsdl.location
YamlPropertySourceLoader can be helpful in spring boot app inject a bean like this
#Bean
public PropertySource<?> yamlPropertySourceLoader() throws IOException {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
PropertySource<?> applicationYamlPropertySource = loader.load("application.yml",
new ClassPathResource("application.yml"), "default");
return applicationYamlPropertySource;
}
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order: Source
base on same you can decide which properties are going to be in effect. If a property key is duplicated, the last declared file will ‘win’ and override.
Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
#TestPropertySource annotations on your tests.
properties attribute on your tests. Available on #SpringBootTest and
the test annotations for testing a particular slice of your
application.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in
an environment variable or system property).
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that has properties only in
random.*.
Profile-specific application properties outside of your packaged
jar
(application-{profile}.properties and YAML variants).
Profile-specific application properties packaged inside your jar
(application-{profile}.properties and YAML variants).
Application properties outside of your packaged jar
(application.properties and YAML variants).
Application properties packaged inside your jar
(application.properties and YAML variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified by setting
SpringApplication.setDefaultProperties).
Edit:
As mentioned in your edit, you are creating new object using below code
ExampleService exampleService = new ExampleService();
System.out.println(exampleService.getWsdlLocation())
This will create object from spring, you should using autowiring
#Autowired
private ExampleService exampleService ;
System.out.println(exampleService.getWsdlLocation())
I have a simple question about PropertySourcesPlaceholderConfigurer and #PropertySource annotation. I have simple class with bean. I would like to inject property from application.properties and some another test.properties wiht #Value annotation. I read in several sources that #PropertySource needs to define staticPropertySourcesPlaceholderConfigurer bean. From documentation:
In order to resolve ${...} placeholders in definitions or
#Value annotations using properties from a PropertySource, one must
register a PropertySourcesPlaceholderConfigurer. This happens
automatically when using in XML, but
must be explicitly registered using a static #Bean method when using
#Configuration classes.
But for me it works fine without this bean. Is Spring in some way auto configures PropertySourcesPlaceholderConfigurer at application startup? Here is my simple example (first property is from application.properties and second from test.properties):
#Configuration
#PropertySource("classpath:test.properties")
public class AppConfiguration {
#Value("${first.property}")
private String firstProp;
#Value("${second.property}")
private String secondProp;
#Bean
public TestModel getModel() {
TestModel model = new TestModel();
model.setFirstProperty(firstProp);
model.setSecondProperty(secondProp);
return model;
}
}
The static PropertySourcesPlaceholderConfigurer bean is registered automatically when missing by PropertyPlaceholderAutoConfiguration class which appears to be introduced in Spring Boot 1.5.0.RELEASE (as there is no on-line javadoc for it in the previous releases).
Interestingly this new auto configuration is not mentioned in Spring Boot 1.5 Release Notes.
Need help, where is the issue?
I have a configuration class which is loading properties as
WebConfig.java
#Configuration
#PropertySource(value={"classpath:application.properties"})
class WebConfig extends WebMvcConfigurerAdapter{
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
I have another configuration class where I am trying to use the properties as
MyServerConfig.java
#Configuration
class MyServerConfig {
#Value("${server.url}")
private String url;
...
}
application.properties
server.url=http://localhost:8080/test/abc
But getting:
java.lang.IllegalArgumentException: Could not resolve placeholder 'server.url'.
Don't know what is missing here? Any thoughts?
Use the #PropertyScan annotation in the class where a certain property will be used:
#Configuration
#PropertyScan("classpath:application.properties")
class MyServerConfig {
#Value( "${server.url}" )
private String url;
}
For getting the values for your #Value variables, the application.properties is not needed to be configured in any special way because this file is always scanned. So remove the #PropertySource annotation and PropertySourcesPlaceholderConfigurer bean.
These are used if you want to add other .properties files (e.g. constants.properties, db-config.properties).
So just remove those and try to run your application again
Very important:
Make sure you scan the class that uses the #Value annotation (If your BootApplication is in some package instead of the 'main' package, add the proper #SpringBootApplication(scanBasePackages = { "com.my.project" }) annotation).
Make sure your application.properties is on your classpath.
Bonus If you are using spring profiles (e.g: prod, dev), you can also have application-prod.properties and application-dev.properties files that will be scanned and included depending on which profile you are running.
I have looked at the below threads and followed things given there. Still my property override is not happening
Spring Boot - Externalized properties
Profile Specific Property Enablement
Spring Boot External Config
I am on Tomcat 8.0.33 and Spring boot starter web and got this in my setenv.sh
export JAVA_OPTS="$JAVA_OPTS -Dlog.level=INFO -Dspring.config.location=file:/opt/jboss/apache-tomcat-8.0.33/overrides/ -Dspring.profiles.active=dev"
And in the overrides folder I got 2 files
1) application.properties
2) application-dev.properties
The application.properties has a single entry in it
spring.profiles.active=dev
I see that the proper log.level is fed to my code which means this command is working. Its just that I am clueless as to why my override is not happening as expected
I don't have any `PropertyPlaceholderConfigurer code in my workspace. I am not even sure if I need 1
I don't use this method to externalise properties. First, I'll try a suggestion for your method and then I'll show you what I'm using.
The suggestion for your method is to use file:/// instead of file:/ as with Spring I found that when not passing the three slashes after the colon it didn't recognise the property.
I've created a sample project for you, available here with instructions.
Now for the method I use.
I define a Configuration file for each profile and I keep the application.properties file under src/main/resources.
Then I use the #Profile and #PropertySource annotations on each configuration file.
For example:
#Configuration
#Profile("dev")
#PropertySource("file:///${user.home}/.devopsbuddy/application-dev.properties")
public class DevelopmentConfig {
#Bean
public EmailService emailService() {
return new MockEmailService();
}
#Bean
public ServletRegistrationBean h2ConsoleServletRegistration() {
ServletRegistrationBean bean = new ServletRegistrationBean(new WebServlet());
bean.addUrlMappings("/console/*");
return bean;
}
}
And
#Configuration
#Profile("prod")
#PropertySource("file:///${user.home}/.devopsbuddy/application-prod.properties")
public class ProductionConfig {
#Bean
public EmailService emailService() {
return new SmtpEmailService();
}
}
I have also got a Configuration file that is valid for all profiles, which I call ApplicationConfig, as follows:
#Configuration
#EnableJpaRepositories(basePackages = "com.devopsbuddy.backend.persistence.repositories")
#EntityScan(basePackages = "com.devopsbuddy.backend.persistence.domain.backend")
#EnableTransactionManagement
#PropertySource("file:///${user.home}/.devopsbuddy/application-common.properties")
public class ApplicationConfig {
}
My src/main/resources/application.properties file looks like the following:
spring.profiles.active=dev
default.to.address=me#example.com
token.expiration.length.minutes=120
Of course I could externalise the spring.profile.active property by passing it as a system property but for my case and for now it's fine.
When running the application, if I pass the "dev" profile, Spring will load all properties and Beans defined in the DevelopmentConfig class plus all those in ApplicationConfig. If I pass "prod", the ProductionConfig and ApplicationConfig properties will be loaded instead.
I'm completing a course on how to create a Spring Boot website with Security, Email, Data JPA, Amazon Web Services, Stripe and much more. If you want, you can register your interest here and you will get notified when the course is open for enrolment.
I want spring boot to read my config from entries in my application.properties but they are not activated. My application.properties contains these entries:
foo.user=nobody
foo.pass=notshared
I can see that this file is being read (I only have the file twice: once in the src-tree and once copied automatically in bin. The files are equal):
2015-03-23 21:55:18.199 DEBUG 25004 --- [main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'classpath:/application.properties'
I have a class called FooConfig:
#Component
#ConfigurationProperties(prefix = "foo")
public class FooConfig {
private String user = "default";
private String pass = "default";
...
}
I have getters and setters for both values.
I AutoWire this config class into my code:
#Component
public class FooFunctions {
#Autowired
public FooFunctions(FooConfig fooConfig) {
log.debug("user={}", fooConfig.getUser());
...
And the problem is that the default value "default" is printed and not the value from the application.properties.
Any hints ? Unfortunately I can not use the actuator yet to display configuration properties because this is a non-web application.
I try all of this on spring boot 1.2.2
In order to make
#ConfigurationProperties(prefix = "foo")
annotation work, your spring boot application must have
#EnableConfigurationProperties
annotation set.
There is no need to set #Component annotation on ConfigurationProperties bean.