X.
https://stackoverflow.com/questions/16373276/predestroy-method-of-a-spring-singleton-bean-not-called
protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
return builder.sources(App.class).registerShutdownHook(true);
}
http://memorynotfound.com/gracefully-shutdown-spring-application-container/
http://fahdshariff.blogspot.com/2013/04/gracefully-shutting-down-spring.html
http://stackoverflow.com/questions/31658170/springbootapplication-exclude-when-componentscanning-other-springbootapplicatio
@Aspect @Component class GreetingServiceMetricsAspect { private final CounterService counterService; @Autowired public GreetingServiceMetricsAspect(CounterService counterService) { this.counterService = counterService; } @AfterReturning(pointcut = "execution(* eu.kielczewski.example.service.greeting.GreetingService.getGreeting(int)) && args(number)", argNames = "number") public void afterCallingGetGreeting(int number) { counterService.increment("counter.calls.get_greeting"); counterService.increment("counter.calls.get_greeting." + number); } @AfterThrowing(pointcut = "execution(* eu.kielczewski.example.service.greeting.GreetingService.getGreeting(int))", throwing = "e") public void afterGetGreetingThrowsException(NoSuchElementException e) { counterService.increment("counter.errors.get_greeting"); } }
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
By default, all endpoints except for
One of its biggest advantages is by default it embeds tomcat as the servlet container, allowing the developer to focus on other important things. Another great thing about Spring Boot is it includes the ability to easily enable what they call Production-Ready or Production-Grade Services. These services allow you to monitor and manage your application when its pushed to production and it's as easy as adding a dependency to your project.
As a part of that they support Elastic Load Balancing which allows one to configure a health check endpoint. It's basically an endpoint you configure in AWS that gets pinged to make sure the EC2 instance is up and running.
Not only does it add a health endpoint, but it also adds: autoconfig, beans, configprops, dump, env, info, metrics, mappings, shutdown (not enabled by default over HTTP), and trace. Like us, you might not want to expose all these endpoints in a production environment. In fact, all we wanted to enable was the health and info endpoints. The following will show you how to disable each service individually and how to re-enable them dynamically at runtime.
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html
Spring Boot Actuator includes a metrics service with ‘gauge’ and ‘counter’ support. A ‘gauge’ records a single value; and a ‘counter’ records a delta (an increment or decrement).
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready
http://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#healthcheck
https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/java/org/springframework/boot/ApplicationTemp.java
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html
https://github.com/spring-projects/spring-loaded
http://blog.codeleak.pl/2017/03/spring-boot-configure-log-level-in.html
Disable security for loggers or for all endpoints
Set either management.security.enabled to false or endpoints.loggers.sensitive to false to disable security. Note that the latter changes only loggers endpoint.
Get selected logger details
Use the following endpoint to get details of a selected logger:
/logger/{logger}
curl -i http://localhost:8080/loggers/ROOT
curl -i http://localhost:8080/loggers/pl.codeleak.demos
Update selected logger level in runtime
Execute a POST request:
curl -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "TRACE"}' http://localhost:8080/loggers/ROOT
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
http://stackoverflow.com/questions/33844580/how-do-i-change-log-level-in-runtime-without-restarting-spring-boot-application
http://www.baeldung.com/spring-boot-actuators
https://www.javacodegeeks.com/2017/03/spring-boot-security-events-actuator.html
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-actuator
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready
loggers Shows and modifies the configuration of loggers in the application.
http://stackoverflow.com/questions/29923682/how-does-one-specify-a-temp-directory-for-file-uploads-in-spring-boot
spring.http.multipart.max-request-size=10MB
spring.http.multipart.enabled=true
spring.http.multipart.location=${java.io.tmpdir}
https://spring.io/guides/gs/uploading-files/
http://stackoverflow.com/questions/27405713/running-code-after-spring-boot-starts
that Lifecycle is the prefered option to perform asynchronous tasks on start/stop stages of the application
http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
http://nixmash.com/java/using-spring-boot-commandlinerunner/
http://www.deepzeafish.xyz/environment-specific-properties-spring-boot.html
http://www.seropian.eu/2015/05/spring-boot-jasypt-easy-encrypted-properties.html
https://github.com/ulisesbocchio/jasypt-spring-boot
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-troubleshoot-auto-configuration
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
https://geowarin.github.io/understanding-spring-boot.html
The
When it finds such a file, the
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
Older Servlet containers don’t have support for the
Spring Boot uses Servlet 3.0 APIs to initialize the
https://spring.io/guides/gs/convert-jar-to-war/
Both of these plugins support that as well. Essentially, you have to reconfigure your project to produce a WAR file and declare the embedded container dependencies as "provided". This ensures that the relevant embedded container dependencies aren’t included in the WAR file.
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging
https://mtdevuk.com/2015/07/16/how-to-make-a-spring-boot-jar-into-a-war-to-deploy-on-tomcat/
https://stackoverflow.com/questions/16373276/predestroy-method-of-a-spring-singleton-bean-not-called
For Spring to call
@PreDestroy
callback method when you application shuts down, you have to add a shutdown hook and close the application context it in. You could attach the hook to JVM using Runtime.getRuntime().addShutdownHook(Thread)
or to Jetty if it provides such an API. Here is how you'd do it with JVM shutdown hook:final ApplicationContext appContext = ... // create your application context
// using one of the various application context classes
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
appContext.close();
}});
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exitprotected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
return builder.sources(App.class).registerShutdownHook(true);
}
http://memorynotfound.com/gracefully-shutdown-spring-application-container/
http://fahdshariff.blogspot.com/2013/04/gracefully-shutting-down-spring.html
1. Register a shutdown hook
Call
https://stackoverflow.com/questions/32654291/spring-boot-rest-with-xml-supportCall
registerShutdownHook()
that is declared in the AbstractApplicationContext
class in order to register a shutdown hook with the JVM. I wrote about Shutdown Hooks in a previous post. They allow your application to perform "clean up" when the JVM exits either naturally or with a kill
/Ctrl+C signal. Spring's shutdown hook closes your application context and hence calls the relevant destroy methods on your beans so that all resources are released (provided that the destroy callbacks have been implemented correctly!). Also, note that no guarantee can be made about whether or not any shutdown hooks will be run if the JVM aborts with the SIGKILL signal (kill -9) on Unix or the TerminateProcess call on MS Windows.
To make this work in Spring Boot without using Jersey we need to add this dependency:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html
You need to opt-in to auto-configuration by adding the
@EnableAutoConfiguration
or @SpringBootApplication
annotations to one of your @Configuration
classes.
If you need to find out what auto-configuration is currently being applied, and why, start your application with the
--debug
switch. This will enable debug logs for a selection of core loggers and log an auto-configuration report to the console.
If you find that specific auto-configure classes are being applied that you don’t want, you can use the exclude attribute of
@EnableAutoConfiguration
to disable them.@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
If the class is not on the classpath, you can use the
You can define exclusions both at the annotation level and using the property.excludeName
attribute of the annotation and specify the fully qualified name instead. Finally, you can also control the list of auto-configuration classes to exclude via the spring.autoconfigure.exclude
property.http://stackoverflow.com/questions/31658170/springbootapplication-exclude-when-componentscanning-other-springbootapplicatio
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration
https://github.com/spring-projects/spring-boot/issues/7020
http://stackoverflow.com/questions/23856977/configure-spring-boot-to-auto-configure-for-only-specific-dependencies-for-testi/23857283#23857283
http://stackoverflow.com/questions/23856977/configure-spring-boot-to-auto-configure-for-only-specific-dependencies-for-testi/23857283#23857283
The
@EnableAutoConfiguration
annotation starts to auto-configure everything what it finds on classpath. You can exclude things via excluding certain auto configuration classes like:@AutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
Similarly you can auto-configure just some of the functionality by
@Import
the auto-configuration classes. Like:@Import({DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
My real world example:
- I have
@EnableAutoConfiguration
located on my main application@Configuration
class - I have a module which uses DB which may be disabled and in that case I don't want to autoconfigure the database at all
- So I excluded the autoconfiguration from main config
- And added the
@Import
on the module config which is guarded by@Conditional
Besides just logging the metrics to JSON, you have more options, like for example:
- Spring Boot Actuator can work with Dropwizard's metrics library. If present on a classpath the metrics are made available through a
MetricRegistry
exposed as a Spring Bean. This not only gives you access to more metric types like histograms, but also you can use it to export metrics to tools like Graphite. - You can use a Java-Zabbix bridge or agent implementation and push them to Zabbix
- It also integrates with JMX messaging, so they can be pushed out to the message broker.
Spring Boot Actuator is also an audit framework. The same things that are done for metrics can also be done for audit messages. The audit events are treated as other Spring application events just being an instances of
private final CounterService counterService;
AuditApplicationEvent
, so you can push them to ApplicationEventPublisher
. Then they can be read using AuditEventRepository
.
public String getGreeting(int number) {
if (number < 1 || number > GREETINGS.length) {
counterService.increment("counter.errors.get_greeting");
throw new NoSuchElementException(String.format("No greeting #%d", number));
}
counterService.increment("counter.calls.get_greeting");
counterService.increment("counter.calls.get_greeting." + (number - 1));
return GREETINGS[number - 1];
}
Besides CounterService
the other one provided by default is GaugeService
that is used to collect a single double
value, i.e. a measured execution time.@Aspect @Component class GreetingServiceMetricsAspect { private final CounterService counterService; @Autowired public GreetingServiceMetricsAspect(CounterService counterService) { this.counterService = counterService; } @AfterReturning(pointcut = "execution(* eu.kielczewski.example.service.greeting.GreetingService.getGreeting(int)) && args(number)", argNames = "number") public void afterCallingGetGreeting(int number) { counterService.increment("counter.calls.get_greeting"); counterService.increment("counter.calls.get_greeting." + number); } @AfterThrowing(pointcut = "execution(* eu.kielczewski.example.service.greeting.GreetingService.getGreeting(int))", throwing = "e") public void afterGetGreetingThrowsException(NoSuchElementException e) { counterService.increment("counter.errors.get_greeting"); } }
https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
By default, all endpoints except for
shutdown
are enabled. If you prefer to specifically “opt-in” endpoint enablement you can use the endpoints.enabled
property. For example, the following will disable all endpoints except for info
:endpoints.enabled=false endpoints.info.enabled=true
Likewise, you can also choose to globally set the “sensitive” flag of all endpoints. By default, the sensitive flag depends on the type of endpoint (see the table above). For example, to mark all endpoints as sensitive except
info
:endpoints.sensitive=true endpoints.info.sensitive=falsehttp://jlorenzen.blogspot.com/2014/07/disable-spring-boot-production-ready.html
One of its biggest advantages is by default it embeds tomcat as the servlet container, allowing the developer to focus on other important things. Another great thing about Spring Boot is it includes the ability to easily enable what they call Production-Ready or Production-Grade Services. These services allow you to monitor and manage your application when its pushed to production and it's as easy as adding a dependency to your project.
As a part of that they support Elastic Load Balancing which allows one to configure a health check endpoint. It's basically an endpoint you configure in AWS that gets pinged to make sure the EC2 instance is up and running.
<
dependency
>
<
groupid
>org.springframework.boot</
groupid
>
<
artifactid
>spring-boot-starter-actuator</
artifactid
>
<
version
>1.1.4.RELEASE</
version
>
</
dependency
>
endpoints.autoconfig.enabled=
false
endpoints.beans.enabled=
false
endpoints.configprops.enabled=
false
endpoints.dump.enabled=
false
endpoints.env.enabled=
false
endpoints.health.enabled=
true
endpoints.info.enabled=
true
endpoints.metrics.enabled=
false
endpoints.mappings.enabled=
false
endpoints.shutdown.enabled=
false
endpoints.trace.enabled=
false
Spring Boot Actuator includes a metrics service with ‘gauge’ and ‘counter’ support. A ‘gauge’ records a single value; and a ‘counter’ records a delta (an increment or decrement).
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready
http://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#healthcheck
https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/java/org/springframework/boot/ApplicationTemp.java
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html
https://github.com/spring-projects/spring-loaded
http://blog.codeleak.pl/2017/03/spring-boot-configure-log-level-in.html
Disable security for loggers or for all endpoints
Set either management.security.enabled to false or endpoints.loggers.sensitive to false to disable security. Note that the latter changes only loggers endpoint.
Get selected logger details
Use the following endpoint to get details of a selected logger:
/logger/{logger}
curl -i http://localhost:8080/loggers/ROOT
curl -i http://localhost:8080/loggers/pl.codeleak.demos
Update selected logger level in runtime
Execute a POST request:
curl -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "TRACE"}' http://localhost:8080/loggers/ROOT
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
http://stackoverflow.com/questions/33844580/how-do-i-change-log-level-in-runtime-without-restarting-spring-boot-application
and than you can use
curl -X "POST" "http://localhost:8080/loggers/de.springbootbuch" \
-H "Content-Type: application/json; charset=utf-8" \
-d $'{
"configuredLevel": "WARN"
}'
Where everything beyond /loggers/ is the name of the logger.
In order to configure a given logger, you
POST
a partial entity to the resource’s URI:{ "configuredLevel": "DEBUG" }
http://www.baeldung.com/spring-boot-actuators
Actuators enable production-ready features to a Spring Boot application – without having to actually implement these things yourself.
They’re mainly used to expose different types of information about the running application – health, metrics, info, dump, env etc.
http://javabeat.net/spring-boot-actuator/1 | management.security.enabled=true |
2 | security.basic.enabled=true |
3 | security.user.name=admin |
4 | security.user.password=admin |
- Cache metrics details are added to the metrics endpoint since the spring boot 1.3.0 release.
The newly added metrics details are:
- The current size of the cache
cache.xxx.size
- The hit ratio
cache.xxx.hit.ratio
- The miss ration
cache.xxx.miss.ratio
https://www.javacodegeeks.com/2017/03/spring-boot-security-events-actuator.html
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-actuator
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready
loggers Shows and modifies the configuration of loggers in the application.
http://stackoverflow.com/questions/29923682/how-does-one-specify-a-temp-directory-for-file-uploads-in-spring-boot
private File convertMultipartFileToFile(MultipartFile file) throws IOException
{
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
Instead, I should have been creating a new File in the designated temporary directory like this:
private File convertMultipartFileToFile(MultipartFile file) throws IOException
{
File convFile = File.createTempFile("temp", ".xlsx"); // choose your own extension I guess? Filename accessible with convFile.getAbsolutePath()
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
spring.http.multipart.max-file-size=10MBspring.http.multipart.max-request-size=10MB
spring.http.multipart.enabled=true
spring.http.multipart.location=${java.io.tmpdir}
https://spring.io/guides/gs/uploading-files/
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
Add the following properties to your existing properties settings:
src/main/resources/application.properties
spring.http.multipart.max-file-size=128KB
spring.http.multipart.max-request-size=128KB
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
@Test
public void should404WhenMissingFile() throws Exception {
given(this.storageService.loadAsResource("test.txt"))
.willThrow(StorageFileNotFoundException.class);
this.mvc.perform(get("/files/test.txt"))
.andExpect(status().isNotFound());
}
https://www.mkyong.com/spring-boot/spring-boot-file-upload-example/
By default, Spring Boot max file upload size is 1MB, you can configure the values via following application properties :
#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
#search multipart
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=10MB
http://stackoverflow.com/questions/27405713/running-code-after-spring-boot-starts
that Lifecycle is the prefered option to perform asynchronous tasks on start/stop stages of the application
http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
To execute some code when the Spring Boot application startup simply add the following
ApplicationStartup
class somewhere in your project (e.g. in the root package) and put your custom code inside the onApplicationEvent
method.@Component
public class ApplicationStartup
implements ApplicationListener<ApplicationReadyEvent> {
/**
* This event is executed as late as conceivably possible to indicate that
* the application is ready to service requests.
*/
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
// here your code ...
return;
}
}
Application events are sent in the following order, as your application runs:
An ApplicationStartedEvent is sent at the start of a run, but before any processing except the registration of listeners and initializers.
An ApplicationEnvironmentPreparedEvent is sent when the Environment to be used in the context is known, but before the context is created.
An ApplicationPreparedEvent is sent just before the refresh is started, but after bean definitions have been loaded.
An ApplicationReadyEvent is sent after the refresh and any related callbacks have been processed to indicate the application is ready to service requests.
An ApplicationFailedEvent is sent if there is an exception on startup.
http://nixmash.com/java/using-spring-boot-commandlinerunner/
A quick post on a cool Spring Boot Interface called CommandLineRunner. With CommandLineRunner you can perform tasks after all Spring Beans are created and the Application Context has been created.
If you want access to the raw command line arguments, or you need to run some specific code once the SpringApplication has started you can implement the CommandLineRunner interface. The run(String… args) method will be called on all Spring beans implementing this interface. You can additionally implement the @Ordered interface if several CommandLineRunner beans are defined that must be called in a specific order.
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Component
public class ApplicationLoader implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(ApplicationLoader.class);
@Override
public void run(String... strings) throws Exception {
StringBuilder sb = new StringBuilder();
for (String option : strings) {
sb.append(" ").append(option);
}
sb = sb.length() == 0 ? sb.append("No Options Specified") : sb;
logger.info(String.format("WAR launched with following options: %s", sb.toString()));
}
}
|
What’s interesting is that the ApplicationLoader class above is in the NixMash Spring JPA RootContext Module, but @SpringBootApplication in the MVC WebContext Module will pick up the class because we added the @Component annotation and implement the CommandLineRunner Interface.
In Spring Boot you do this by following the naming schema application-<environment>.properties for your property files like application-devel.properties or application-production.properties
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class myconfig {
private string server;
private string user;
private string pwd;
// ...getters and setters here
}
@EnableConfigurationProperties tells Spring to check for classes annotated with @ConfigurationProperties, which then can be used to tell Spring which prefix in your property file this bean should represent. @Configuration tells Spring that this class declares bean methods
http://www.seropian.eu/2015/05/spring-boot-jasypt-easy-encrypted-properties.html
https://github.com/ulisesbocchio/jasypt-spring-boot
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-troubleshoot-auto-configuration
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
https://geowarin.github.io/understanding-spring-boot.html
The
EnableAutoConfigurationImportSelector
uses SpringFactoriesLoader#loadFactoryNames
of Spring core. SpringFactoriesLoader will look for jars containing a file with the path META-INF/spring.factories
.When it finds such a file, the
SpringFactoriesLoader
will look for the property named after our configuration file. In our case, org.springframework.boot.autoconfigure.EnableAutoConfiguration
.http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
Older Servlet containers don’t have support for the
ServletContextInitializer
bootstrap process used in Servlet 3.0. You can still use Spring and Spring Boot in these containers but you are going to need to add a web.xml
to your application and configure it to load an ApplicationContext
via a DispatcherServlet
.Spring Boot uses Servlet 3.0 APIs to initialize the
ServletContext
(register Servlets
etc.) so you can’t use the same application out of the box in a Servlet 2.5 container. https://spring.io/guides/gs/convert-jar-to-war/
Both of these plugins support that as well. Essentially, you have to reconfigure your project to produce a WAR file and declare the embedded container dependencies as "provided". This ensures that the relevant embedded container dependencies aren’t included in the WAR file.
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging
To build a war file that is both executable and deployable into an external container you need to mark the embedded container dependencies as “provided”, e.g:
<packaging>war</packaging> <!-- ... --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- ... --> </dependencies>
https://mtdevuk.com/2015/07/16/how-to-make-a-spring-boot-jar-into-a-war-to-deploy-on-tomcat/