Why Spring Boot created?
There was lot of difficulty to setup Hibernate Datasource, Entity Manager, Session Factory, and Transaction Management. It takes a lot of time for a developer to set up a basic project using Spring with minimum functionality.

What Spring Boot does?
Spring Boot does all of those using AutoConfiguration and will take care of all the internal dependencies that your application needs — all you need to do is run your application. It follows “Opinionated Defaults Configuration” Approach to reduce Developer effort.Spring Boot looks at a) Frameworks available on the CLASSPATH b) Existing configuration for the application. Based on these, Spring Boot provides basic configuration needed to configure the application with these frameworks. This is called Auto Configuration.

How to use Spring Boot ?

Spring Version 4

  1. Spring Framework 4.0 provides support for several Java 8 features
  2. Java EE version 6 or above with the JPA 2.0 and Servlet 3.0 specifications
  3. Groovy Bean Definition DSL- external bean configuration using a Groovy DSL
  4. Core Container Improvements
    1. The @Lazy annotation can now be used on injection points, as well as on @Bean definitions.
    2. The @Description annotation has been introduced for developers using Java-based configuration
    3. Using generics as autowiring qualifiers
    4. Beans can now be ordered when they are autowired into lists and arrays. Both the @Order annotation and Ordered interface are supported.
    5. A generalized model for conditionally filtering beans has been added via the @Conditional annotation

Spring Version 5

  1. Functional programming with Kotlin
  2. Reactive Programming Model.The Reactive Streams API is officially part of Java 9. In Java 8, you will need to include a dependency for the Reactive Streams API specification.
  3. @Nullable and @NotNull annotations will explicitly mark nullable arguments and return values. This enables dealing null values at compile time rather than throwing NullPointerExceptions at runtime.
  4. Spring Framework 5.0 now supports candidate component index as an alternative to classpath scanning..Reading entities from the index rather than scanning the classpath.Loading the component index is cheap. Therefore the startup time with the index remains constant as the number of classes increase. While for a compoent scan the startup time increases significantly.
  5. requires Java 8 as a minimum JDK version.Spring 5 is fully compatible with Java 9.
  6. Servlet 3.1,JMS 2.0,JPA 2.1,Hibernate5,JAX-RS 2.0,Bean Validation 1.1,JUnit 5

Java 7 Features:

  1. Usage of Strings in Switch Statement
  2. Diamond Operator – the diamond operator allows you to write more compact (and readable) code by saving repeated type arguments
  3. Try with Resources
  4. Multiple Exception Handling
  5. Suppressed Exceptions
  6. Allows Binay Literals – Binary Literal are expressing Integer Values in terms of Binary Value by adding the prefix 0b or 0B to the integral value.For more on BinayLiteral click here

Java 8 Features:

  1. Lambda Expressions
  2. Java Stream API for Bulk Data Operations on Collections.
  3. Static and Default method in Functional Interfaces
  4. forEach() method in Iterable interface
  5. Functional Interfaces
  6. Collection API improvements

Java 9 Features:

  1. Factory Methods for Immutable List, Set, Map and Map.Entry
  2. Private methods in Interfaces
  3. Reactive Streams
  4. JShell: the interactive Java REPL

Java 10 Features:

  1. Local-Variable Type Inference
  2. Application Class-Data Sharing
  3. default set of root Certification Authority (CA) certificates in the JDK
  4. Garbage Collector Interface

Java 11 Features:

  1. Java 11 JDK is not free for usage on commercial purpose
  2. No need to compile.typing >>Java in command prompt will compile and run java
  3. Remove the Java EE and CORBA Modules –
  4. Java String Methods – isBlank(), lines(), strip(), stripLeading(), stripTrailing()

Why Lambda Expressions

Now Lets Iterate through the simple ArrayList

Without Lambda Expressions

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

for (int number : numbers) 
{
    System.out.println(number);
}

We iterate the collection externally, explicitly pulling out and processing the items one by one. Now through Lambda Expressions, we are using an internal iteration the JIT compiler could optimize it processing the items in parallel or in a different order. These optimizations are impossible if we iterate the collection externally as we are used to doing in Java and more in general with the imperative programming.

With Lambda Expressions

numbers.forEach((Integer value) -> System.out.println(value));

(or)

numbers.forEach(value -> System.out.println(value));

Apart from the above reason Lambdas allows us to

  • Enable to treat functionality as a method argument, or code as data.
  • A function that can be created without belonging to any class.
  • A lambda expression can be passed around as if it was an object and executed on demand.
  • It reduces the line of code.
  • It Supports Sequential and Parallel execution by passing behavior in methods with collection stream API
  • Using Stream API and lambda expression we can achieve higher efficiency (parallel execution) in the case of bulk operations on collections

Java 8 Lambda uses JVM Opcode – invokedynamic

The Following code will result in Anonymous class being created when you compile the code.
So if you have 10 anonymous classes then it would be 10 more classes like(ClassName$1.class,ClassName$2.class….ClassName$10.class) in the final jar.

AccountService accountServiceAnonymous = new AccountService(){
    public void createAccount(){
        Account account = new Account();
        save(account);
    }
};

But Java 8 lambda uses invokedynamic to call lambdas thus if you have 10 lambdas it will not result in any anonymous classes thus reducing the final jar size.

AccountService accountServiceLambda = () -> {
    Account account = new Account();
    save(account);
}

Append and Prepend Using Regular Expressions

Append Operation

Find What    : ^[A-Z].*
Replace With : $&~
Search Mode  : Regular Expressions

Input

Apple
Mango
Orange

Output

Apple~
Mango~
Orange~

Prepend Operation

Find What    : ^[A-Z].*
Replace With : ~$&
Search Mode  : Regular Expressions

Input

Apple
Mango
Orange

Output

~Apple
~Mango
~Orange

Replace Empty Lines

Edit -> Line Operations -> Remove Empty Lines

Prepending based on Certain Condition(Lines Starting with Numbers)

Find What    : ^[1-9;].*
Replace With : $&?
Search Mode  : Regular Expressions

Input

1.How are you
Good
2.What is your Name
Mugil

Output

1.How are you?
Good
2.What is your Name?
Mugil
ஓம் பூர் புவஸ்ஸூவ
தத் சவிதுர்வரேண்யம்
பர்கோ தேவஸ்ய தீமஹி
தியோ யோ ந: ப்ரசோதயாத்|

காயத்திரி’ என்னும் ஒலியின் அளவைக் கொண்டு இந்த மந்திரம் இயற்றப்பட்டதால் “காயத்திரி மந்திரம்”.நமது புத்தியை இயங்கச் செய்யும் பரமாத்மாவை நாம் வணங்குவோம் என்பது சுருக்கமான பொருள்.சூரியனுடைய ஒளியை தியானிக்கின்றோம் என்பதால் கண்களை மூடிய நிலையில் சூரிய ஒளியில் நின்று இதைச் சொல்ல வேண்டும் என்பது யதார்த்தமான விஷயம்

Om Bhuur-Bhuvah Svah
Tat-Savitur-Varennyam |
Bhargo Devasya Dhiimahi
Dhiyo Yo Nah Pracodayaat ||

Full long version

Om bhUH, Om bhuvaH, Om svaH, Om mahaH, Om janaH, Om tapaH, Om satyam
Om tat savitur varenyaM, bhargo, devasya dhImahi, dhIyo yo naH, prachodayAt
Om Apo jyotiH rasoamRitaM brahma, bhur bhuvas svar Om.

A Japanese soap factory had a problem: they sometimes shipped empty boxes, without the soap inside. This was due to the way the production line was set up, and people with experience in designing production lines will tell you how difficult it is to have everything happen with timings so precise that every single unit coming out of it is perfect 100% of the time. Customers who come all the way to the supermarket would end up buying someone else’s product.

Understanding how important that was, the CEO of the soap factory got the top people in the company together and they decided to start a new project, in which they would hire an external engineering company to solve their empty boxes problem, as their engineering department was already too stretched to take on any extra effort.

The project followed the usual process: budget and project sponsor allocated, RFP, third-parties selected, and six months (and $8 million) later they had a fantastic solution — on time, on budget, high quality and everyone in the project had a great time. They solved the problem by using some high-tech precision scales that would sound a bell and flash lights whenever a soap box weighing less than it should. The line would stop, and someone had to walk over and yank the defective box out of it, pressing another button when done.

A while later, the CEO decides to have a look at the ROI of the project: amazing results! No empty boxes ever shipped out of the factory after the scales were put in place. Very few customer complaints, and they were gaining market share. “That’s some money well spent!” – he says, before looking closely at the other statistics in the report. It turns out, the number of defects picked up by the new high precision scales was “zero” after three weeks of production use. It should’ve been picking up at least a dozen a day, so maybe there was something wrong with the report. He filed a bug against it, and after some investigation, the engineers come back saying the report was actually correct. The scales really weren’t picking up any defects, because all boxes that got to that point in the conveyor belt were good.

Puzzled, the CEO travels down to the factory, and walks up to the part of the line where the high precision scales were installed. A few feet before it, there was a $ 20 desk fan, blowing the empty boxes out of the belt and into a bin.

“Oh, that — one of the guys put it there ’cause he was tired of walking over every time the bell rang”, says one of the workers.
Moral of the Story: Everyone has a “solution” sometimes requiring an expenditure of “8 million bucks”. It requires an engineer with a high spirit of innovation and ingenuity to come up with a “$ 20 – simple cost-effective solution”!

Below is a code example of CustomClass Loader which Servers use internally for HotCode Swap without restarting the server.When you change the Quote in ServerImpl.java file the file should be reloaded by selecting the RELOAD option while running Client.java

IServer.java

public interface IServer {
	public String getQuote();
}

ServerImpl.java

public class ServerImpl implements IServer{
	@Override
    public String getQuote() {
        return "Its Working Man";
    }
}

Client.java

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Client {
    static ClassLoader cl;
    static IServer server;

    public static void reloadServer() throws Exception {
        URL[] urls = new URL[]{new URL("file:///D:/java/HotDeplyment/appclasses")};
        System.out.println("Reloaded.....");
        cl = new URLClassLoader(urls);
        server  = (IServer) cl.loadClass("com.mugil.org.ServerImpl").newInstance();
    }

    public static void main(String [] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        reloadServer();
        while (true) {
            System.out.print("Enter QUOTE, RELOAD, or QUIT: ");
            String cmdRead = br.readLine();
            String cmd = cmdRead.toUpperCase();
            if (cmd.equals("QUIT")) {
                return;
            } else if (cmd.equals("QUOTE")) {
                System.out.println( server.getQuote());
            } else if (cmd.equals("RELOAD")) {
            	reloadServer();
            }
        }
    }
}

The Above code is not working as windows is not clearing cached .class files or JAR files. So the alternative is to try with the below Custom Class Loader(MyURLClassLoader) which in turn extends URLClassLoader again.

MyURLClassLoader.java

import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.jar.JarFile;

public class MyURLClassLoader extends URLClassLoader {

	public MyURLClassLoader(URL[] urls, ClassLoader parent) {
	    super(urls, parent);
	}

    /**
     * Closes all open jar files
     */
    public void close() {
        try {
            Class clazz = java.net.URLClassLoader.class;
            Field ucp = clazz.getDeclaredField("ucp");
            ucp.setAccessible(true);
            Object sunMiscURLClassPath = ucp.get(this);
            Field loaders = sunMiscURLClassPath.getClass().getDeclaredField("loaders");
            loaders.setAccessible(true);
            Object collection = loaders.get(sunMiscURLClassPath);
            for (Object sunMiscURLClassPathJarLoader : ((Collection) collection).toArray()) {
                try {
                    Field loader = sunMiscURLClassPathJarLoader.getClass().getDeclaredField("jar");
                    loader.setAccessible(true);
                    Object jarFile = loader.get(sunMiscURLClassPathJarLoader);
                    ((JarFile) jarFile).close();
                } catch (Throwable t) {
                    // if we got this far, this is probably not a JAR loader so skip it
                }
            }
        } catch (Throwable t) {
            // probably not a SUN VM
        }
        return;
    }
}

In the below code the CustomClass Loader is called to load the classes which inturn calls the Super Class loader which is again Loaders from URL Class Loader.Once it is done we have defined a custom close method which closes the JAR files or .class files which is loaded by class loader.

TestClassLoader.java

package com.mugil.org;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;

public class TestClassLoader {
	static ClassLoader cl;
    static IServer server;
	
	public static void main(String[] args) throws Exception {
		
		while(true) {
			try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			TestClassLoader obj = new TestClassLoader();
			obj.loadAndInstantiate();			
			System.out.println(server.getQuote());			
			}
			catch (Exception e){
				
			}
			finally {
				try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
			}
		}    
	}
	
	void loadAndInstantiate() throws Exception {
	    MyURLClassLoader cl = null;
	    try {	    	
	        File file = new File("D:\\java\\HotDeplyment\\bin\\Sample.jar");
	        String classToLoad = "com.mugil.org.ServerImpl";
	        URL jarUrl = new URL("file:" + file.getAbsolutePath());
	        cl = new MyURLClassLoader(new URL[] {jarUrl}, getClass().getClassLoader());
	        Class loadedClass = cl.loadClass(classToLoad);
	        Object o = loadedClass.getConstructor().newInstance();
	        server  = (IServer) o;
	        
	    } finally {
	        if(cl != null)
	            cl.close();
	    } 
	}
}

Since the infinite while loop is called indefinitely with the thread sleep interval of every 3 seconds we replace the JAR file in the middle which takes the class from the new JAR file loaded.You need to change the ServerImpl.java file and build the JDK before you want to see the changes

Output

.
.
Its Working Man
Its Working Man
Its Working Man
Its Working Man
Its Working 
Its Working 
Its Working 
.
.

The Above code is not working either

Why Tomcat Server does not needs restart if changes are done in servlet and JSP?
Tomcat is capable of adding/modifying classpath to Web Application classloader at runtime. Tomcat will be having their custom Classloader implementation which allows them to add the classpaths at runtime.a new classloader is created for the Servlet/JSP with Application classloader as parent classloader. And the new classloader will load the modified class again.

It is always best to reload the entire application incase changes are done to servlet. If you were simply to reload one class, in isolation, you might break dependencies or miss some initialization steps. Therefore, it’s much safer to reload the entire application clicking deploy option in tomcat server.JSPs on the other hand, when properly coded, shouldn’t have anything in them by markup text. So reloading a single JSP, without reloading the entire app, should be safe. By default, tomcat is started in development mode, which means JSP-derived servlets recompiled when a change is detected.

In the web.xml you need to set the below config

<servlet>
   .
   .
    <!-- Add the following init-param -->
    <init-param>
        <param-name>development</param-name>
        <param-value>true</param-value>
    </init-param>
   .
   .
   .
</servlet>

In the Server.xml reloadable should be set to true

<Context path="/simple" docBase="webapps/simple"  debug="0" reloadable="true" ></Context>

More on how CustomClass loader works for Hot Deployment here

How it Works

  1. We have JSON file with Location and Name of Factory Class
  2. Using Configuration.java we read the JSON File and read the Configuration
  3. We run TasteFoodFromMenu.java by supplying the JSON file Location as Input
  4. Now by the above method the JAR’s could be built independently and by changing the JSON file we could make changes and deploy the code without restarting the Server

For more detail refer here

Configuration.java

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Configuration {

    public static Configuration loadConfiguration(String fileName) throws IOException {    	
    	//Read Name of File
        Path path = FileSystems.getDefault().getPath(fileName);
        
        //Read Contents of File
        String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
        
        ObjectMapper mapper = new ObjectMapper();
        
        //Map Location and FactoryType
        Configuration config = mapper.readValue(contents, Configuration.class);
        return config;
    }

    private String factoryType;
    private String location;


    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getFactoryType() {
        return factoryType;
    }

    public void setFactoryType(String factoryType) {
        this.factoryType = factoryType;
    }
}

TasteFoodFromMenu.java

public class TasteFoodFromMenu {
	  public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
	        Configuration configuration = Configuration.loadConfiguration(args[0]);
	        String location = configuration.getLocation();
	        URL url = new URL(location);
	        URLClassLoader ucl = new URLClassLoader(new URL[]{url});
	        Class<IFoodFactory> cls = (Class<IFoodFactory>) Class.forName(configuration.getFactoryType(), true, ucl);
	        IFoodFactory cameraFactory = cls.newInstance();
	        IFood camera = cameraFactory.prepareFood(); 
	        camera.serveFood();
	    }
}

config.json

{
  "factoryType": "com.mugil.food.ChineseFoodFactory",
  "location": "file:///D:/java/ReadConfFromJSON/lib/FoodMenu.jar"
}