-
Notifications
You must be signed in to change notification settings - Fork 88
guide spring configuration
There usually is a main configuration registered with main Spring Boot App, but differing configurations to support automated test of the application can be defined using profiles (not detailed in this guide).
For a complete documentation, see the Spring Boot Reference Guide.
With spring-boot you provide a simple main class (also called starter class) like this: com.devonfw.mtsj.application
@SpringBootApplication(exclude = { EndpointAutoConfiguration.class })
@EntityScan(basePackages = { "com.devonfw.mtsj.application" }, basePackageClasses = { AdvancedRevisionEntity.class })
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@ComponentScan(basePackages = { "com.devonfw.mtsj.application.general", "com.devonfw.mtsj.application" })
public class SpringBootApp {
/**
* Entry point for spring-boot based app
*
* @param args - arguments
*/
public static void main(String[] args) {
SpringApplication.run(SpringBootApp.class, args);
}
}
In an devonfw application this main class is always located in the <basepackage>
of the application package namespace (see package-conventions). This is because a spring boot application will automatically do a classpath scan for components (spring-beans) and entities in the package where the application main class is located including all sub-packages. You can use the @ComponentScan
and @EntityScan
annotations to customize this behaviour.
If you want to map spring configuration properties into your custom code please see configuration mapping.
For basic bean configuration we rely on spring boot using mainly configuration classes and only occasionally XML configuration files. Some key principle to understand Spring Boot auto-configuration features:
-
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies and annotated components found in your source code.
-
Auto-configuration is non-invasive, at any point you can start to define your own configuration to replace specific parts of the auto-configuration by redefining your identically named bean (see also
exclude
attribute of@SpringBootApplication
in example code above).
Beans are configured via annotations in your java code (see dependency-injection).
For technical configuration you will typically write additional spring config classes annotated with @Configuration
that provide bean implementations via methods annotated with @Bean
. See spring @Bean documentation for further details. Like in XML you can also use @Import
to make a @Configuration
class include other configurations.
More specific configuration files (as required) reside in an adequately named subfolder of:
src/main/resources/app
In case you are still using dozer, you will find further details in bean-mapper configuration.
The abstract base class BaseWebSecurityConfig
should be extended to configure web application security thoroughly.
A basic and secure configuration is provided which can be overridden or extended by subclasses.
Subclasses must use the @Profile
annotation to further discriminate between beans used in production and testing scenarios. See the following example:
BaseWebSecurityConfig
for Production and Test@Configuration
@EnableWebSecurity
@Profile(SpringProfileConstants.JUNIT)
public class TestWebSecurityConfig extends BaseWebSecurityConfig {...}
@Configuration
@EnableWebSecurity
@Profile(SpringProfileConstants.NOT_JUNIT)
public class WebSecurityConfig extends BaseWebSecurityConfig {...}
See WebSecurityConfig.
A websocket endpoint is configured within the business package as a Spring configuration class. The annotation @EnableWebSocketMessageBroker
makes Spring Boot registering this endpoint.
package your.path.to.the.websocket.config;
...
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
...
Here is a list of common properties provided by the Spring framework.
For a general understanding how spring-boot is loading and boostrapping your application.properties
see spring-boot external configuration.
The following properties files are used in devonfw application:
-
src/main/resources/application.properties
providing a default configuration - bundled and deployed with the application package. It further acts as a template to derive a tailored minimal environment-specific configuration. -
src/main/resources/config/application.properties
providing additional properties only used at development time (for all local deployment scenarios). This property file is excluded from all packaging. -
src/test/resources/config/application.properties
providing additional properties only used for testing (JUnits based on spring test).
For other environments where the software gets deployed such as test
, acceptance
and production
you need to provide a tailored copy of application.properties
. The location depends on the deployment strategy:
-
standalone run-able Spring Boot App using embedded tomcat:
config/application.properties
under the installation directory of the spring boot application. -
dedicated tomcat (one tomcat per app):
$CATALINA_BASE/lib/config/application.properties
-
tomcat serving a number of apps (requires expanding the wars):
$CATALINA_BASE/webapps/<app>/WEB-INF/classes/config
In this application.properties
you only define the minimum properties that are environment specific and inherit everything else from the bundled src/main/resources/application.properties
. In any case, make very sure that the classloader will find the file.
The configuration for spring and Hibernate is already provided by devonfw in our sample application and the application template. So you only need to worry about a few things to customize.
Obviously you need to configure which type of database you want to use as well as the location and credentials to access it. The defaults are configured in application.properties
that is bundled and deployed with the release of the software. The files should therefore contain the properties as in the given example:
database.url=jdbc:postgresql://database.enterprise.com/app
database.user.login=appuser01
database.user.password=************
database.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
database.hibernate.hbm2ddl.auto=validate
For further details about database.hibernate.hbm2ddl.auto
please see here. For production and acceptance environments we use the value validate
that should be set as default. In case you want to use Oracle RDBMS you can find additional hints here.
If your application supports multiples database types, set spring.profiles.active=XXX
in src/main/resources/config/application.properties
choose database of your choice. Also, one has to set all the active spring profiles in this application.properties
and not in any of the other application.properties
.
In order to support encrypted passwords in spring-boot application.properties
all you need to do is to add jasypt-spring-boot as dependency in your pom.xml
(please check for recent version here):
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
This will smoothly integrate jasypt into your spring-boot application. Read this HOWTO to learn how to encrypt and decrypt passwords using jasypt.
Next, we give a simple example how to encypt and configure a secret value.
We use the algorithm PBEWITHHMACSHA512ANDAES_256
that provides strong encryption and is the default of jasypt-spring-boot-starter
.
However, different algorithms can be used if perferred (e.g. PBEWITHMD5ANDTRIPLEDES
).
java -cp ${M2_REPO}/org/jasypt/jasypt/1.9.3/jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI password=masterpassword algorithm=PBEWITHHMACSHA512ANDAES_256 input=secret ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator ----ENVIRONMENT----------------- Runtime: AdoptOpenJDK OpenJDK 64-Bit Server VM 11.0.5+10 ----ARGUMENTS------------------- input: secret password: masterpassword ivGeneratorClassName: org.jasypt.iv.RandomIvGenerator algorithm: PBEWITHHMACSHA512ANDAES_256 ----OUTPUT---------------------- PoUxkNjY2juQMCyPu6ic5KJy1XfK+bX9vu2/mPj3pmcO4iydG6mhgZRZSw50z/oC
Of course the master-password (masterpassword
) and the actual password to encrypt (secret
) are just examples.
Please replace them with reasonable strong passwords for your environment.
Further, if you are using devonfw-ide you can make your life much easier and just type:
devon jasypt encrypt
Now the entire line after the OUTPUT
block is your encrypted secret.
It even contains some random salt so that multiple encryption invocations with the same parameters (ARGUMENTS
) will produce a different OUTPUT
.
The master-password can be configured on your target environment via the property jasypt.encryptor.password
. As system properties given on the command-line are visible in the process list, we recommend to use an config/application.yml
file only for this purpose (as we recommended to use application.properties
for regular configs):
jasypt:
encryptor:
password: masterpassword
masterpassword
is just an example that your replace with your actual master password.
Now you are able to put encrypted passwords into your application.properties
and specify the algorithm.
spring.datasource.password=ENC(PoUxkNjY2juQMCyPu6ic5KJy1XfK+bX9vu2/mPj3pmcO4iydG6mhgZRZSw50z/oC)
jasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256
application.properties
file can be version controlled (git-opts) and without knowing the masterpassword nobody is able to decrypt this to get the actual secret back.
To prevent jasypt to throw an exception in dev or test scenarios you can simply put this in your local config (src/main/config/application.properties
and same for test
, see above for details):
jasypt.encryptor.password=none
This documentation is licensed under the Creative Commons License (Attribution-NoDerivatives 4.0 International).