Wednesday, September 28, 2016

Spring Boot


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() {
   protected SpringApplicationBuilder configure(final SpringApplicationBuilder builder) {
       return builder.sources(App.class).registerShutdownHook(true);
1. Register a shutdown hook 
Call 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:
You need to opt-in to auto-configuration by adding the @EnableAutoConfiguration or @SpringBootApplication annotations to one of your @Configurationclasses.
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.

If the class is not on the classpath, you can use the 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.
You can define exclusions both at the annotation level and using the property.
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 = {
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 AuditApplicationEvent, so you can push them to ApplicationEventPublisher. Then they can be read using AuditEventRepository.
private final CounterService counterService;
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 doublevalue, 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"); } }
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:
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:
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.

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).
Disable security for loggers or for all endpoints

Set either 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:

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
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"
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.
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-security</artifactId>

  • 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
  • The hit ratio
  • The miss ration
Spring Boot provides cache statistics for EhCache, Hazelcast, Infinispan, JCache and Guava.
loggers Shows and modifies the configuration of loggers in the application.
private File convertMultipartFileToFile(MultipartFile file) throws IOException
        File convFile = new File(file.getOriginalFilename());
        FileOutputStream fos = new FileOutputStream(convFile); 
        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); 
        return convFile;
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes) {;
                "You successfully uploaded " + file.getOriginalFilename() + "!");

        return "redirect:/";

Add the following properties to your existing properties settings:
    public void should404WhenMissingFile() throws Exception {

By default, Spring Boot max file upload size is 1MB, you can configure the values via following application properties :
#search multipart
that Lifecycle is the prefered option to perform asynchronous tasks on start/stop stages of the application
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.
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.
  public void onApplicationEvent(final ApplicationReadyEvent event) {
    // here your code ...

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.
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.

public class ApplicationLoader implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(ApplicationLoader.class);
    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;"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 or


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
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.
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.
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.
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:
    <!-- ... -->
        <!-- ... -->


Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts