I am trying to load the required parameters like accessURI,client_id, client_secret from properties file like below. It never loads the properties, I see many sites mention this as example. It is working if I tries to set it explicitly.
In this example
https://dzone.com/articles/build-a-spring-boot-app-with-secure-server-to-serv
#Bean()
#ConfigurationProperties(prefix ="my.oauth2.client")
protected ClientCredentialsResourceDetails oAuthDetails() {
return ClientCredentialsResourceDetails();
But it never loaded the properties so I need to change to use set methods.I am not able to figure out why it did not load, I believe I cannot mention this in #EnableConfigurationProperties as it does not have the configuration configured.
I tried searching but could not find a matching reason.
Basically, the binding of properties to class members works as described in the example.
The properties have to be present either as YAML or properties file:
spring:
security:
oauth2:
client:
registration:
oauth:
client-id: XXXXXX
client-secret: YYYYYYY
scope: openid
redirect-uri: http://redirect
access-token-uri: https://token
client-authentication-method: basic
authorization-grant-type: client_credentials
Then the #ConfigurationProperties annotation has to be declared with the correct prefix. In this example it is "spring.security.oauth2.client.registration.oauth".
#Bean
#ConfigurationProperties(prefix ="spring.security.oauth2.client.registration.oauth")
protected ClientCredentialsResourceDetails oAuthDetails() {
return new ClientCredentialsResourceDetails();
}
As stated in the Spring Boot documentation you normally do not have to set the #EnableConfigurationProperties annotation unless you are developing your own auto-configuration.
But if you are working on a non Spring Boot project the #EnableConfigurationProperties annotation has to be declared, describing the class where we want to use the #ConfigurationProperties annotation:
#Configuration()
#EnableConfigurationProperties(MyProperties.class)
public class MyConfig {
}
with
#ConfigurationProperties(prefix="myproperties")
public class MyProperties {
}
Alternatively you can also use configuration property scanning which works similarly to the component scanning by declaring the #ConfigurationPropertiesScan annotation:
#SpringBootApplication
#ConfigurationPropertiesScan({ "my.app" })
public class MyApplication {
}
Hope, this helps. Pero
Related
The Spring Boot documentation says that to use the #ConfigurationProperties annotation
You also need to list the properties classes to register in the
#EnableConfigurationProperties annotation, as shown in the following
example:
and gives this code:
#Configuration
#EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
But in the very next paragraph says:
Even if the preceding configuration creates a regular bean for
AcmeProperties, we recommend that #ConfigurationProperties only deal
with the environment and, in particular, does not inject other beans
from the context. Having said that, the #EnableConfigurationProperties
annotation is also automatically applied to your project so that any
existing bean annotated with #ConfigurationProperties is configured
from the Environment.
Suggesting that listing a #ConfigurationProperties bean under an #EnableConfigurationProperties annotation is not necessary.
So which is it? Experimentally, I've seen that if I annotate a bean with #ConfigurationProperties it gets properties injected to it as expected without needing to list it in #EnableConfigurationProperties, but if this is the case then why list anything that has a #ConfigurationProperties annotation under #EnableConfigurationProperties, as is shown in the documentation? Does it make any kind of difference?
As M. Deinum referred #EnableConfigurationProperties Is for enabling support of #ConfigurationProperties. If you take a look to the annotation Java Doc you can see:
Enable support for ConfigurationProperties annotated beans. ConfigurationProperties beans can be registered in the standard way (for example using Bean #Bean methods) or, for convenience, can be specified directly on this annotation. [...]
For example, let's say you have a class whose responsibility is to read and store information from your application.yml / application.properties that is required to make a connection to different databases. You annotate it with #ConfigurationProperties.
Then, you typically have a #Configuration annotated class that provides a DataSource #Bean to your application. You can use the #EnableConfigurationProperties to link it to the #ConfigurationProperties class and init your data sources accordingly.
Here is a small example:
application.yml
data-sources:
db1:
url: "jdbc:postgresql://localhost:5432}/db1"
username: test
password: test
db2:
url: "jdbc:postgresql://localhost:5432}/db2"
username: test
password: test
DataSourcesConfiguration
#ConfigurationProperties
public class DataSourcesConfiguration {
private Map<String, BasicDataSource> dataSources;
public void setDataSources(Map<String, BasicDataSource> dataSources) {
this.dataSources = dataSources;
}
Map<String, BasicDataSource > getDataSources() {
return dataSources;
}
}
DataSourceConnectionConfiguration
#Configuration
#EnableConfigurationProperties(DataSourcesConfiguration.class)
public class DatabaseConnectionConfiguration implements Provider<Connection> {
private DataSourcesConfiguration dataSourcesConfiguration;
public DatabaseConnectionConfiguration(DataSourcesConfiguration dataSourcesConfiguration) {
this.dataSourcesConfiguration = dataSourcesConfiguration;
}
#Bean
public DataSource dataSource() {
// Use dataSourcesConfiguration to create application data source. E.g., a AbstractRoutingDataSource..
}
}
It took me a while to reach to this post but would like to add here so that others may get benefited.
#ConfigurationProperties - Used to bind a class with an externalized property file. Very powerful and must be used to separate out bean classes with configuration entity class.
#Configuration - Creates a Spring bean of configuration stereotype.
#EnableConfigurationProperties - Creates a binding between a configuration entity class and Spring configuration stereotype so that after injection within a service properties can be retrieved easily.
If we look at the code below:
#Configuration #EnableConfigurationProperties #ConfigurationProperties(prefix="ar1")
public class ar1Settings { }
#Configuration tells Spring to treat this as a configuration class and register it as a Bean
#EnableConfigurationProperties tells Spring to treat this class as a consumer of application.yml/properties values
#ConfigurationProperties tells Spring what section this class represents.
My understanding is that if you don't need to specify the section of the property file, then #ConfigurationProperties can be omitted.
#EnableConfigurationProperties imports EnableConfigurationPropertiesRegistrar which enables support for #ConfigurationProperties annotated beans.
#ConfigurationProperties is an annotation for externalized configuration, it is to be applied to a bean configuration class or method annotated with #Bean eg
#ConfigurationProperties(prefix = "some-prefix")
public SomePrefix prefixBean() {
return new SomePrefix();
}
To load the properties and bind them to properties within the method or the class that match the prefix.
ps: some-prefix binds to SomePrefix because of spring's support for Relaxed binding.
Before springboot 2.2, You could do either of the following:
#Configuration
#ConfigurationProperties(prefix = "some-prefix")
public class ConfigProperties {
//...some code
}
or
#Configuration
#EnableConfigurationProperties(SomeClassToBeBounded.class)
public class ConfigProperties {
along with
#ConfigurationProperties(prefix = "some-prefix")
public class SomeClassToBeBounded{
//...some code
}
From springboot 2.2
You can do it in a much easier way:
#ConfigurationProperties(prefix = "some-prefix")
#ConfigurationPropertiesScan
public class ConfigProperties {
//...some code
}
With this, the classpath scanner enabled by #SpringBootApplication finds the ConfigProperties class, even though we didn't annotate this class with #Component.
I have configured the allowed origins for CORS in the Spring yml configuration as follows.
endpoints:
cors:
allowed-origins: http://client.local
allow-credentials: true
But it wasn't applied until I added a Java configuration as follows
#Configuration
#EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Value("${endpoints.cors.allowed-origins}")
private String allowedOrigins;
#Value("${endpoints.cors.allow-credentials}")
private boolean allowCredentials;
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(allowedOrigins)
.allowCredentials(allowCredentials);
}
}
I want to keep the yml configuration and discard the Java configuration, why is the yml config not applied?
I know, it might be too late, but I'll try...
Have you added spring-boot-starter-actuator to your dependencies?
Instead of using custom properties use endpoints provided by Spring Boot.
Ex:
management.endpoints.web.cors.allowed-origins=http://domain:port
Spring Boot Application.properties configuration
Config
#Configuration
#PropertySources({
#PropertySource("classpath*:properties/test-database.properties")
})
public class DataSourceConfiguration {//...
}
Prop location
D:\Projects\opti\dao\src\main\resources\properties\test-database.properties
D:\Projects\opti\dao\src\main\resources marked as resource folder.
To avoid this kind of problem the issue is to set the jboss.server.config.dir in VM arguments like that :
-Djboss.server.config.dir="[jboss_repository]/server/[default-all-standard-standalone]/conf" –server
and u set PropertySource like this :
#Configuration
#PropertySource("file:${jboss.server.config.dir}/file.properties")
Or you set ur property like that
#PropertySource(value = "classpath:application.properties")
When executed, properties will be imported from the application.properties file, located in the classpath root.
It isn't clear well the your problem considering the details of your question, but a typical problem whit #PropertySource is that yuo have configure a spring bean for manage the properties. In old years in which xml was the best way for configure Spring you used a namespace configuration that configure a spring bean for use proeprties in your bean, mainly with #Value. In java config for benefit of same behaviour you have configure a bean like belove:
#Bean
public static PlaceholderConfigurerSupport propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
I hope that this can help you
I am new to Swagger and have implemented Swagger UI with spring mvc, I want to disable UI on production/live environment. I am struggling to figure it out.
This is what I am using
SwaggerConfig.java
#Configuration
#EnableSwagger2
public class SwaggerConfig {
}
RestController.java
#RestController
#Api(value="city", description="Operations pertaining to City Data")
#RequestMapping(value="/v1/city")
public class RestController {
#ApiOperation(value = "View city by stateId or stateName")
#RequestMapping(value="/search",method=RequestMethod.POST)
public ResponseEntity<Object> getCityBystateId(#RequestBody StateDto stateDto,Model model){
}
}
Look into the Spring's profile mechanism that lets you register different beans in different environments
When you bootstrap it according to doc, you can annotate your swagger config class on a class level with e.g. #Profile("dev"), thus enabling the swagger configuration for the environment of your choice
#Configuration
#EnableSwagger2
#Profile("dev")
public class SwaggerConfig {
}
Another way is to use a reverse proxy to reject access to Swagger Api on your production environment.
In this case your production installation is exactly the same as your development/test environment (then more compliant with DevOps method) and you can continue to access your Swagger API with internal calls.
I have an authentication service that I want to autoconfigure at runtime but that will be mocked up for development and testing. I would like to use the #ConfigurationProperties feature to define the necessary parameters, but I also need to be able to only conditionally create the AuthenticationManager instances, depending on whether a live service is configured.
The approach I would like to take is to use something like #ConditionalOnBean(AuthProperties.class), but
Spring Boot creates a bean of my #ConfigurationProperties class regardless of whether the properties are present. I can apply validation annotations to the fields, but then the context won't start at all if a live service is not configured.
Is there a clean way to make a configuration section conditional on having the properties specified in an #ConfigurationProperties class without repeating the property names in #ConditionalOnProperty?
Can't you just use profile of your application-some_profile.properties file and then create your properties bean conditionally like this
#Profile("some_profile")
#Component
#ConfigurationProperties(prefix = "some.selector")
public Class YourConfiguration{
private property option;
}
this way it only gets created conditionally depending which profile you select live or mock.
Than you can either use selected profile for your #Configuration authentication classes for separate approaches or follow with #ConditionalOnBean. That's what profiles are for or maybe I misunderstood the question.
I had a similar problem and I could resolve it with this approach using Spring Boot and Java 8, hope it helps someone:
#Configuration
#PropertySources({
#PropertySource("classpath:integration.properties"),
#PropertySource(value = "classpath:integration-${spring.profiles.active}.properties", ignoreResourceNotFound = true)
})
#ConfigurationProperties(prefix = "integration")
public class IntegrationProperties {
private String user;
private String password;
private String projectId;
....
}
integration.properties
integration.user=User
integration.password=Password
integration.project-id=123
integration-prod.properties
integration.project-id=897
Spring Boot will create the bean using the properties file, and for production (using the profile prod) it will use the other file and override the project-id. The ignoreResourceNotFound = true will avoid the FileNotFoundException on startup when you are not using the prod profile.