I am starting to learn Spring annotations. I'm currently using the #PropertySource annotation in my Configuration Class to resolve properties values and everything works fine, but then I read about PropertySourcesPlaceholderConfigurer.
When or why I should use that?
From #PropertySource javadoc
...
Note, however, that explicit registration
of a PropertySourcesPlaceholderConfigurer via a static #Bean
method is typically only required if you need to customize configuration such as the
placeholder syntax, etc. See the "Working with externalized values" section of
Configuration #Configuration's javadocs and "a note on
BeanFactoryPostProcessor-returning #Bean methods of Bean #Bean's
javadocs for details and examples.
Specifically, if no bean post-processor (such as a PropertySourcesPlaceholderConfigurer) has registered an embedded value resolver for the ApplicationContext, Spring will register a default embedded value resolver which resolves placeholders against property sources registered in the Environment.
...
Well, if simple words if you need set up or get more control over property configuration bean such as PropertySourcesPlaceholderConfigureryou could define it. Otherwise it can be ommited.
But if you use version of Spring prior 4.3.0, this bean has to be declared for resolve #Value.
For get more details:
6.Configuration using Raw Beans in Spring 3.0 – the PropertyPlaceholderConfigurer
javadoc #PropertySource
I hope it'll a little help you)
Related
I have dependency in my spring boot project which fetches values of some properties using Spring's EnvironmentPostProcessor.
Now these properties are database credentials and not everyone has access to the credential since there is no dev environment for the db in question. I just want to change the configuration that the credentials don't get fetched on dev or local environment on application startup as that would result in a error and the application will fail to start.
Class A implements EnvironmentPostProcessor{}
I tried to use #Lazy annotation on the Class Annoteted with #ConfigurationProperties. I also tried using my own BeanFactoryPostProcessor (with #Order(HighestPrecedence) to programmatically set the A to lazy load, but it gets called before my BeanFactoryPostProcessor's postProcessBeanFactory method.
Is what I'm trying to achieve possible and am I going about it the wrong way?
#Lazy is only to be used with #Bean or #Component (Or any #Component-based annotations ex. #Service)
Take note: You can also add it to a #Configuration class, but that just means that all Beans in the class are annotated with #Lazy
#Lazy is a bit of a weird annotation in general; it should be seen as an IF possible then lazy load. If some other bean needs the lazy bean, the lazy bean will be initialized. (It's like the Pirate code, more of a guideline than an enforced rule)
Finally, marking #ConfigurationProperties with #Lazy seems a bit odd. As Spring will need these Configuration property "beans" to create the Spring Context.
However, the common use case for #Lazy is a failing database connection, preventing the application from starting. See the question if that is what you are running into.
Summary:
You can configure your repositories to be lazy-loaded with:
spring.data.jpa.repositories.bootstrap-mode=lazy
Last remark (Me just guessing)
If you wish to change properties once your application is already running, I would look at the following tutorial. It goes into manually reloading configuration and also #RefreshScope.
According to documentation EnvironmentPostProcessors must be registered via META-INF/spring.factories:
Allows for customization of the application's Environment prior to the
application context being refreshed. EnvironmentPostProcessor
implementations have to be registered in META-INF/spring.factories,
using the fully qualified name of this class as the key.
Implementations may implement the Ordered interface or use an #Order
annotation if they wish to be invoked in specific order.
I have a confusion regarding datasource autoconfiguration in Spring-boot. From what I have read, we have to specify the datasource properties in the form spring.datasource.*. But my application code works fine if I supply property name in the form SPRING_DATASOURCE_*. Is there any reason that I am missing, due to which it works? Please clarify.
I think You've come across a feature of spring boot called Relaxed Binding.
It allows using some "relaxed" rules for binding to ConfigurationProperties. So essentially both ways of definition have the same effect in your application.
Here you can find a link to the relevant chapter in the official documentation
Spring Boot has so-called Relaxed Binding
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-relaxed-binding which allows you to define configuration in different ways:
acme.my-project.person.first-name
acme.myProject.person.firstName
acme.myProject.person.firstName
acme.my_project.person.first_name
ACME_MYPROJECT_PERSON_FIRSTNAME
The latter is often used when passed via environment variables.
My question is the following:
Is it possible to ignore XML configuration for HibernateValidator, i.e. exclude validation.xml parsing in a SpringBoot application?
I do not have the need for a validation.xml in my application, but I see that when the application starts up, it tries to parse this file.
I found this in the Hibernate Validator documentation (https://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/validator-xmlconfiguration.html):
It is even possible to ignore the XML configuration completely via Configuration.ignoreXmlConfiguration().
What I see is, that in the LocalValidatorFactoryBean.afterPropertiesSet() method, the configuration is created for the validator. This bean has a method called postProcessConfiguration(Configuration configuration), which is called before the validatorFactory is built from the configuration.
It seemed an ideal place to call the ignoreXmlConfiguration() method, what the documentation suggested.
I tried to extend this LocalValidatorFactoryBean, so that I can implement this call in the above mentioned method. Then I tried to load this bean via java configuration class.
Unfortunately some bootstrapping mechanism already uses the Spring provided bean, before it finds mine, the two beans run at the same time. I saw the message saying that XML configuration is ignored the with the bean I created, however, this solution did not help, because the Spring provided bean is not substituted with mine.
I also tried to find if there is any application property that I can use, or exclude some autoconfiguration, but no luck.
Any ideas? :)
UPDATE:
I tried excluding the HibernateJPAAutoConfiguration, it didn't help.
If you dont need hibernate validator then remove all dependency related to hibernate validator from pom.xml file.
you can also try #EnableAutoConfiguration(excludes=) annotation adding on your Application class to exclude default validation configuration.
like #SpringBootApplication(exclude = {HibernateJpaAutoConfiguration.class,DataSourceAutoConfiguration.class} })
I have several spring boot applications in which I want to place a custom annotation (in some bean). The annotation will have one field (e.g. propertyValue). That value I want to add to the Environment as a part of a new PropertySource.
My idea is to create a bean that will inject Environment and then add a new PropertySource to it. The missing piece is how to connect custom annotation with this bean.
Any ideas?
So you want to use different property file for different environment. Spring Boot handles this already without need for custom beans or annotations.
Just use Profile-Specific Configuration Spring Boot feature. You can define profile via system property (e.g. -Dspring.profiles.active=PROD-US-EAST-REGION)
I'm attempting to use the spring-cloud stack for a project that would use Zuul. In my organization we have a custom configuration stack that is xml-based and does property composition and hierarchical overrides. Because of the way this configuration is handled, I've struggled to create a PropertySource for it.
My custom PropertySource must use my Config bean, but because the PropertySources are initialized during the bootstrapping of spring boot, the application context is not fully initialized yet and I can't get to my custom Bean that exposes our xml-based configuration system.
#ConfigurationProperties appears to be entirely biased toward .properties and .yaml files. The Config bean is initialized in an ApplicationContextInitializer. Is there a way to delay the resolution of the ConfigurationProperties within the various services so I can construct my custom property source using my Config bean after it is initialized?
I originally attempted (well before asking the question) to create a custom PropertySourceLocator in my config (as mentioned by Dave Syer and well documented in the link he gave) and register it with my own spring.factories (Again, demonstrated in the helpful link given by Spencer Gibb in the comment.) The problem is that my property source needs to be configured after some work that is done in an ApplicationContextInitializer and the property sources all seem to be resolved before that occurs (at least those wired in as a factory for org.springframework.cloud.bootstrap.BootstrapConfiguration). I guess I hinted at this by stating that I needed a particular bean in my PropertySource that I couldn't get from the ApplicationContext at the time.
Anyway, to get around that, I am now registering the property source in an PriorityOrdered ApplicationContextInitializer to take place after another one that initializes my config object. Something like: context.getEnvironment().getPropertySources().addFirst(myPropertySource);
This seems to get my property source into the environment at the correct time and allows me to perform customization of the context before hand as needed.
In Spring Cloud you would need to register some BootstrapConfiguration (per the user guide: http://projects.spring.io/spring-cloud/spring-cloud.html#customizing-bootstrap-property-sources) that has a PropertySourceLocator bean. It shouldn't be any harder than that.
P.S. #ConfigurationProperties is not biased toward .properties and .yaml files - it binds to the Environment which knows nothing about file formats.