Sunday, September 5, 2021

SpringBoot: Features: SpringApplication

Below are a few SpringBoot features corresponding to SpringApplication

StartUp Logging

·         To add additional logging during startup, override logStartupInfo(boolean) in subclass of SpringApplication

Lazy Initialization

·         Beans are initialized when they are needed instead of application start up

·         Pros:

o   Reduces startup - time & memory

·         Cons:

o   Can delay the discovery of a problem in bean misconfiguration until bean is created which otherwise would have been detected at the time of startup

o   Need to make sure that JVM has sufficient memory to accommodate Lazy beans, not only the eager beans, hence fine tuning needs to be done early

·         Enable

o   lazyInitialization method on SpringApplicationBuilder

o   setLazyInitialization method on SpringApplication

o   setting spring.main.lazy-initialization property to true in properties/yaml file

o   Enabling on certain beans - @Lazy(true), Disabling for certain beans @Lazy(false)

Application Availability

·         Application components can retrieve availability state by injecting ApplicationAvailability interface & calling methods on it

·         Spring Boot provides Kubernetes HTTP probes for “Liveness” and “Readiness” with Actuator Health Endpoints

·         Event Order is as follows

o   ApplicationStartingEvent: started but before any processing

o   ApplicationEnvironmentPreparedEvent: Before context is created

o   ApplicationContextInitializedEvent: ApplicationContext is created

o   ApplicationPreparedEvent: After bean definitions are loaded

o   ApplicationStartedEvent: Before application & command-line runners are called

o   AvaiabilityChangeEvent: After LivenessState.CORRECT

o   ApplicationReadyEvent: Aefore application & command-line runners are called

o   AvaiabilityChangeEvent: ReadinessState.ACCEPTING_TRAFFIC

o   ApplicationFailedEvent: If there is exception on startup

·         Apart from these WebServerInitializedEvent and ContextRefreshedEvent are also sent

·         To identify whether the event is for ApplicationContext or child context, listener bean can be implemented ApplicationContextAware so that it can compare if the event published is for it’s context

·         Liveness State

o   Whether its internal state allows it to work correctly or recover by itself if it is failing

o   If Liveness is broken, infrastructure should restart the application

o   Internal state of Spring Boot applications is represented by ApplicationContext

·         Readiness State

o   Whether application is ready to handle the traffic

o   An application is considered ready as soon as ApplicationRunner and CommandLinRunner are called

Application Arguments

·         If you need to access the SpringApplication.run(…) arguments you can inject Spring ApplicationArguments bean

Application and Command-Line Runner

·         If you need to run some specific code before SpringApplication.run(…) completes, you can implement ApplicationRunner or CommandLineRunner interface

·         Both the interface offers same functionality with single run() method which is called just before SpringApplication.run(…) completes

·         Well suited for tasks that should execute after application startup but before it starts accepting traffic

·         If there are multiple application or command-line interface implementation, you can add @Order to execute them in the order intended

·         CommandLineRunner has access to application arguments as String array whereas ApplicationRunner uses ApplicationArguments interface to access arguments passed to SpringApplication.run(…) method

Listener & Runner

·         ApplicationRunner: Access application arguments using ApplicationArguments interface

·         CommandLineRunner: Access application arguments as String array

·         ApplicationListener: Listener for different ApplicationEvent events

·         @EventListener: Listener for different ApplicationEvent events

Application Exit

·         Each Spring Application registers a shutdown hook with JVM to ensure ApplicationContext closes gracefully

Application Startup Tracking

·         During application startup SpringApplication and ApplicationContext perform many tasks related application lifecycle, bean lifecycle or processing application events

·         ApplicationStartup interface implementation allows you to track the application startup sequence using StartupSteps object

·         SpringBoot ships with BufferingApplicationStartup, which is meant for buffering statup steps and draining them into external metrics system

·         Application can ask for bean of type BufferingApplicationStartup in any component

·         SpringBoot can also be configured to setup startup endpoints to provide this information in JSON format

SpringBoot: DevTools basics

Spring Boot DevTools

·         Dependency is spring-boot-devtools

·         Caching is by default disabled in dev environments, as this helps developer to identify the issues due to property/data changes quickly

·         Logging: For web applications, if you want log all incoming requests, which handler is processing it, the response outcome, etc., then turn on spring.mvc.log-request-details

·         Restart: Applications that use devtools will automatically restart once file on classpath changes

·         Restart Technology of Spring Boot is

o   Application files are loaded in restart classloader

o   File that do not change like thirdparty jar files are loaded in base classloader

o   When application is restarted, only restart classloader is re-created, much faster

·         Trigger File: if you do not want restarts on each file change use trigger file spring.devtools.restart.trigger-file. Any update to a file will trigger a check, restart will only occur if devtools has detected change in trigger file

·         Live Reload: Devtools includes embedded LiveReload server, so that if there is change in file browser will refresh automatically. You can disable it by setting spring.devtools.livereload.enabled property to false

·         Profiles: Profiles are not supported in devtools properties/yaml files

·         Remote Support: Devtools remote support is available using spring.devtools.remote.secret property, but considering security risk, should only be used in trusted network or with SSL, should not be used in prod env 

SpringBoot: Configuration Classes & Running Application

 

@Configuration

·         Spring recommends primary source of configuration as a single class with @Configuration (i.e. Java configuration over XML configuration)


·         If you have additional configuration classes, use @Import annotation to import those in @Configuration class


·         XML configuration can also be imported in Java using @ImportResource annotation to load XML configuration files


@SpringBootConfiguration

·         An alternative to Springs @Configuration that enables registration of extra beans in the context

·         Import additional configuration classes

·         Configuration detection in your integration test i.e. Spring Test Framework


@EnableAutoConfiguration

·         Should be added to @Configuration class


·         A class can be excluded from Auto-configuration using attributes, exclude (if class is on classpath) or excludeName (fully qualified name, if not on classpath)


@ComponentScan

·         Spring recommends constructor injection and scanning components using @ComponentScan


·         @ComponentScan detects @Component, @Service, @Repository, @Controller, etc. and automatically registers it as Spring Bean


@SpringBootApplication

·         This single annotation includes 3 annotations mentioned above @SpringBootConfiguration, @EnableAutoConfiguration and @ComponentScan


Running Application

·         java -jar target/myapplication-0.0.1-SNAPSHOT.jar

·         It is also possible to run packaged application in debugging mode, doing so lets you attach debugger to your packaged application

·         java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \ -jar target/myapplication-0.0.1-SNAPSHOT.jar

Using Maven plugin “mvn spring-boot:run” run compiles and runs the app

SpringBoot: SpringBoot Application Starters

Below is a quick summary of various SpringBoot Application Starters and their usage

Starter Name

Usage

spring-boot-starter

Core starter, including auto-configuration support, logging & YAML

spring-boot-starter-web

Web apps including RESTFul, Spring MVC, uses Tomcat as default container

spring-boot-starter-security

Spring Security

spring-boot-starter-data-rest

For exposing Spring Data repositories over REST using Spring Data Rest

spring-boot-starter-test

Testing applications using JUnit Jupiter, Mockito and Hamcrest

spring-boot-starter-jersey

Building RESTFul web applications using JAX-RS and Jersey (an alternative to spring-boot-starter-web)

spring-boot-starter-data-jdbc

Spring Data JDBC

spring-boot-starter-jdbc

JDBC with HikariCP connection pool

spring-boot-starter-oauth2-client

Using OAuth2/OpenID Connect client features

spring-boot-starter-oauth2-resource-server

Using Spring Security’s OAuth2 resource server feature

spring-boot-starter-json

Reading and writing JSON

spring-boot-starter-data-mongodb

MongoDB document-oriented DB and Spring Data MongoDB

spring-boot-starter-data-mongodb-reactive

MongoDB document-oriented DB and Spring Data MongoDB Reactive

spring-boot-starter-mail

Using Java Mail and Spring Framework’s email sending support

spring-boot-starter-activemq

JMS messaging using Apache ActiveMQ

spring-boot-starter-amqp

Spring AMQF and RabbitMQ

spring-boot-starter-batch

Spring Batch

spring-boot-starter-quartz

Using Quartz scheduler

spring-boot-starter-cache

Spring Framework’s cache support

spring-boot-starter-validation

Spring Java Bean validation with Hibernate Validator

spring-boot-starter-data-ldap

Spring Data LDAP

spring-boot-starter-data-elasticsearch

Elasticsearch search, analytics engine and Spring Data Elasticsearch

spring-boot-starter-data-redis

Using Redis key-value data store and Spring Data Redis and Lettuce client

spring-boot-starter-data-redis-reactive

Redis key-value data store and Spring Data Redis reactive and Lettuce client

spring-boot-starter-freemarker

Build MVC web applications using FreeMarker views

spring-boot-starter-groovy-templates

Build MVC web applications using Groovy Template views

spring-boot-starter-mustache

Build web applications using Mustache views

spring-boot-starter-thymeleaf

Build MVC web applications using Thymeleaf views

spring-boot-starter-integration

Using Spring Integration

spring-boot-starter-jooq

Using JOOQ to access SQL DB. Alternative to spring-boot-starter-data-jpa and spring-boot-starter-jdbc

spring-boot-starter-jta-atomikos

JTA transactions using Atomikos

spring-boot-starter-rsocket

Building RSocket clients & servers

spring-boot-starter-webservices

Spring Web Services

spring-boot-starter-webflux

Building Webflux apps using Spring’s Reactive support

spring-boot-starter-websocket

Building WebSocket apps using Springs WebSocket support

spring-boot-starter-hateoas

Hypermedia based RESTFul web apps with Spring MVC & Spring HATEOAS

spring-boot-starter-data-cassandra

Cassandra distributed DB and Spring Data Cassandra

spring-boot-starter-data-cassandra-reactive

Cassandra distributed DB and Spring Data Cassandra Reactive

spring-boot-starter-artemis

JMS messaging using Apache Artemis

spring-boot-starter-aop

Aspect oriented programming using Spring AOP and AspectJ

spring-boot-starter-data-couchbase

Couchbase document oriented and Spring Data Couchbase

spring-boot-starter-data-couchbase-reactive

Couchbase document oriented and Spring Data Couchbase Reactive

spring-boot-starter-data-neo4j

Neo4j graph DB and Spring Data Neo4j

spring-boot-starter-data-r2dbc

Spring Data R2DBC

spring-boot-starter-actuator

Helps you monitor and manage your app

Friday, August 20, 2021

Spring Core: A few ways to create and inject beans using spring annotations

In this article, we will see a few important ways to create and inject beans using spring annotations.

Let's check this out using an example

Client is the client class, which is loading application context by registering DemoConfig class (@ComponentScan annotation) and getting Vehicle bean using context.

       


package sboot.basicannotations;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Client {
	public static void main(String args[]) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(DemoConfig.class);
		ctx.refresh();
		Vehicle myVehicle = ctx.getBean("vehicle", Vehicle.class);
		System.out.println("Context created...start creating a Vehicle now");
		myVehicle.testVehicle();
		ctx.close();
	}
}

Class DemoConfig defines a few other beans using @Bean annotation which are required for Vehicle creation.

       


package sboot.basicannotations;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class DemoConfig {
	
	@Bean
	public Engine getEngine() {
		return new Engine();
	}
	
	@Bean
	public Body getBody() {
		Body body = new Body();
		body.setSeats(getSeats());
		body.setColor(getColor());
		return body;
	}
	
	@Bean 
	public Seats getSeats() {
		return new Seats();
	}
	
	@Bean
	public Color getColor() {
		return new Grey();
	}
}

The output of the code is


Vehicle bean is instantiated using application context and @Component annotation

Engine is instantiated using @Bean annotation and injected into Vehicle using constructor injection

Body is instantiated using @Bean annotation and injected into Vehicle using @Autowired annotation

Seats is instantiated using @Bean annotation and injected into Body using setter injection

Color is an interface instantiated using @Bean annotation, which is implemented by class Grey

Color (Grey) is injected into Body using setter injection

Vehicle created successfully...


       


package sboot.basicannotations;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Vehicle {
	
	private Engine engine;
	
	//Constructor injection
	public Vehicle(Engine engine) {
		this.engine = engine;
	}
	
	@Autowired
	private Body body;//@Autowired for injecting Body

	public void testVehicle() {
		engine.addEngine();
		body.addBody();
		//Seats & Color will be added in the Body
		System.out.println("Vehicle created successfully...");
	}
}


package sboot.basicannotations;

public class Engine {
	
	public void addEngine() {
		System.out.println("Engine is instantiated using @Bean annotation and injected into Vehicle using constructor injection");
	}
}

package sboot.basicannotations;

public class Body {
	
	private Seats seats;
	//setter injection
	public void setSeats(Seats seats) {
		this.seats = seats;
	}
	
	private Color color;
	//setter injection
	public void setColor(Color color) {
		this.color = color;
	}
	
	public void addBody() {
		System.out.println("Body is instantiated using @Bean annotation and injected into Vehicle using @Autowired annotation");
		seats.addSeats(4);
		System.out.println("Color is an interface instantiated using @Bean annotation, which is implemented by class Grey");
		color.addColor();
	}
}


package sboot.basicannotations;

public class Seats {
	public void addSeats(int noOfSeats) {
		System.out.println("Seats is instantiated using @Bean annotation and injected into Body using setter injection");
	}
}

package sboot.basicannotations;

public interface Color {
	public void addColor();
}

package sboot.basicannotations;

public class Grey implements Color {

	@Override
	public void addColor() {
		System.out.println("Color (Grey) is injected into Body using setter injection");
	}
}

SpringBoot: Features: SpringApplication

Below are a few SpringBoot features corresponding to SpringApplication StartUp Logging ·          To add additional logging during startup...