What is the difference between Multithreading vs Multiprocessing?
Multiprocessing is more than one process in execution where as Multithreading is executing multiple threads within same process. One of the main requirement of MultiProcessing is Multi Core Processor.

Multiprocessing: In a cinema, multiple movies are screened simultaneously in different theaters. Each screening represents a separate process. For instance, one theater might be showing an action movie, another might be showing a romantic comedy, and a third might be screening a documentary. Each screening operates independently, with its own audience and projection equipment.

Multithreading: Within a single screening, there are different tasks being performed concurrently to ensure a smooth movie-watching experience. For example, while the movie is playing, the cinema staff might be selling tickets at the box office, preparing popcorn at the concession stand, and monitoring the theater for any disturbances. These tasks can be seen as threads within the same process (screening). They share resources such as the cinema lobby, staff members, and facilities.

What is Context Switching?
A context switch (also sometimes referred to as a process switch or a task switch) is the switching of the CPU (central processing unit) from one process or thread to another.
Irrespective of Single or Multi Core Context Switching happens.

  1. suspending the progression of one process and storing the CPU’s state (i.e., the context) for that process somewhere in memory
  2. Retrieving the context of the next process from memory and restoring it in the CPU’s registers
  3. Returning to the location indicated by the program counter (i.e., returning to the line of code at which the process was interrupted) in order to resume the process.

Should Context Switch Happen Frequenlty or Less?
No. If that happens, It would be resource consuming and no task gets Completed.If that happens less, You see process hanging. Context Switching should be always decided by Operating system by taking no of threads.

Difference between Concurrency and Parallelism
You and your friend has visited restaurant and seated in a table.

You(Processor) have been tasked to Eat and Sing at same Time. If you take a bite – Stop Eating – Start Singing – Sing few lines – Stop Singing – Resume Eating this is concurrency in action
You(Processor1) and Your Friend(Processor2) have been tasked to Eat and Sing where one person sings and another eats at same time. This is Parallelism.

Concurrency is when two or more tasks can start, run, and complete in overlapping time periods. It doesn’t necessarily mean they’ll ever both be running at the same instant. context switching is a key part of enabling concurrency in a single-core system For example, multitasking on a single-core machine.In Concurrency Interruptability exists

Parallelism is when tasks literally run at the same time, e.g., on a multicore processor.In Parallelism Independabality exists.

Concurrency                 Concurrency + parallelism
(Single-Core CPU)           (Multi-Core CPU)
 ___                         ___ ___
|th1|                       |th1|th2|
|   |                       |   |___|
|___|___                    |   |___
    |th2|                   |___|th2|
 ___|___|                    ___|___|
|th1|                       |th1|
|___|___                    |   |___
    |th2|                   |   |th2|

In both cases we have concurrency from the mere fact that we have more than one thread running.If we ran this program on a computer with a single CPU core, the OS would be switching between the two threads, allowing one thread to run at a time.If we ran this program on a computer with a multi-core CPU then we would be able to run the two threads in parallel – side by side at the exact same time.

Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.

How do you explain the following Scenarios?

Scenario 1:

 
                     Completed               Progressing
Timeline    <----------------------->|<-------------------------------->
      P1    |-----------|--------|------------|------|-----------------|
                 T1         T2         T3        T4         T5   

Scenario 2:

 
                Completed                    Progressing
Timeline    <---------------->|<----------------------------------------->
      P1    |--------|--------|---------|-----|--------|--------|--------|
                 T1      T2       T3       T1      T3      T4       T5

Scenario 3:

 
                     Completed                            Progressing
Timeline    <-------------------------------------->|<------------------->
      P1    |--------|--------|---------|-----|--------|--------|--------|
                 T1      T2       T3       T1      T6      T4       T2
      P2    |--------|--------|---------|-----|--------|--------|--------|
                 T2      T1       T1       T2      T3      T6       T3

Scenario 4:

 
                     Completed                            Progressing
Timeline    <-------------------------------------->|<------------------->
      P1    |--------|--------|---------|-----|--------|--------|--------|
                 T1      T2       T3       T1      T6      T2       T2
      P2    |--------|--------|---------|-----|--------|--------|--------|
                 T4      T5       T4       T7      T5      T4       T8

Scenario 1:
Completed Thread: T1, T2 (2)
Progressing Thread: T3 (1)

Neither Concurrent Nor Parallel – Sequential Execution

Scenario 2:
Completed Thread: T2 (1)
Progressing Thread: T1,T3 (>2)

Concurrent Not Parallel

Scenario 3:
Completed Thread: T1,T2 (2)
Progressing Thread: T3,T4,T6 (>3)

Concurrent and Parallel Execution

Scenario 4:
Completed Thread P1: T1,T3
Progressing Thread P1: T2,T6

Completed Thread P2: T8
Progressing Thread P2: T4,T5

In the above keeping the status of the completed and progressing threads aside, being Multi Core processor the threads are not shared
among the processor. This is example of

Parallel Not concurrent

  1. An application can be concurrent but not parallel, which means that it processes more than one task at the same time, but no two tasks are executing at the same time instant.
  2. An application can be parallel — but not concurrent, which means that it processes multiple sub-tasks of a task in multi-core CPU at the same time.
  3. An application can be neither parallel — nor concurrent, which means that it processes all tasks one at a time, sequentially.
  4. An application can be both parallel — and concurrent, which means that it processes multiple tasks concurrently in multi-core CPU at the same time.

What is Thread in Java?
Thread is an independent path of execution.

How Program, Process, Thread and Task are related?

  1. Program contains Multiple Process.
  2. Process is instance of Program in Execution. When the Process starts, it would always start with a Single Thread. From there the No of Threads increases by the Way program has written.
  3. Threads is instance of Program in Execution.Threads within the process share the same memory as the process. A thread is a basic unit of CPU utilization, consisting of a program counter, a stack, and a set of registers. A thread of execution results from a fork of a computer program into two or more concurrently running tasks.
  4. Task is a set of program instructions that are loaded in memory. The Piece of runnable code which is loaded or Set of instruction processed by Memory is Task. A “Task” is a piece of work that will execute, and complete at some point in the future.

Two process runs on different memory space unless forked, but all threads share same memory space.

Difference between Thread and Task
Suppose you are running a Resturant. You have four Orders and Four Chef. A Order is a thread, a Chef is a processor, and a Cooking is a task. The problem you face is how to efficiently schedule the Chef and Orders so that the tasks get done as quickly as possible.

A Task means an action or work you want to do. A Thread may be one of the doer or worker performing that work.

Why should I prefer Thread over process?
Inter-thread communication (sharing data etc.) is significantly simpler to program than inter-process communication.
Context switches between threads are faster than between processes. That is, it’s quicker for the OS to stop one thread and start running another than do the same with two processes.

Example:
Applications with GUIs typically use one thread for the GUI and others for background computation. The spellchecker in MS Office, for example, is a separate thread from the one running the Office user interface. In such applications, using multiple processes instead would result in slower performance and code that’s tough to write and maintain.

It entirely depends on the design perspective whether to go for a thread or process. When I want to set of logically co-related operations to be carried out parallel. For example, if you run a Notepad++ there will be one thread running in the foreground as an editor and other thread running in background auto saving the document at regular intervals so no one would design a process to do that autosaving task separately.

What is the difference between Asynchronous vs synchronous execution?
synchronous – When you execute something synchronously, you wait for it to finish before moving on to another task. You are in a queue to get a movie ticket. You cannot get one until everybody in front of you gets one, and the same applies to the people queued behind you.

asynchronous -When you execute something asynchronously, you can move on to another task before it finishes. i.e. You are in a restaurant with many other people. You order your food. Other people can also order their food, they don’t have to wait for your food to be cooked and served to you before they can order. In the kitchen, restaurant workers are continuously cooking, serving, and taking orders. People will get their food served as soon as it is cooked.

Synchronous (one thread):

Single Thread  |--------A--------||--------B--------|                  

Synchronous (Multi-Threaded):

Thread A |--------A--------|
Thread B                   |--------B--------|
Thread C                                     |--------C--------|

ASynchronous (One thread):

           A-Start ------------------------------------------ A-End   
               | B-Start -----------------------------------------|--- B-End   
	       |    |      C-Start ------------------- C-End      |      |   
	       |    |       |                           |         |      |
  	       V    V       V                           V         V      V      
Single thread->|--A-|---B---|--C-|-A-|-C-|--A--|-B-|--C---|---A---|--B-->|

Asynchronous (Multi-Threaded):

Thread A ->     |----A-----|
Thread B ----->     |-----B-----------| 
Thread C --------->     |-------C----------|

Thread Implementation using Runnable vs Callable
A Callable needs to implement call() method while a Runnable needs to implement run() method. A Callable can return a value and throw checked exception. Runnable interface for fire and forget calls, especially when you are not interested in result of the task execution. A Callable can be used with ExecutorService#invokeXXX(Collection> tasks) methods but a Runnable cannot be. Refer here

One important difference: the run() method in the Runnable interface returns void; the call() method in the Callable interface returns an object of type T. This allows you to access a response object easily.

public interface Runnable {
    void run();
}

public interface Callable<V> {
    V call() throws Exception;
}

What is ExecutorService?
It manages a pool of worker threads, and allows you to submit tasks for execution. ExecutorService abstracts away many of the complexities associated with the lower-level abstractions like raw Thread. It provides mechanisms for safely starting, closing down, submitting, executing, and blocking on the successful or abrupt termination of tasks (expressed as Runnable or Callable). ExecutorService handles creation, management, and reusability of threads, making it easier to handle concurrent tasks in multithreaded applications. Refer here

An ExecutorService is a utility in Java that provides a way to execute tasks concurrently and hides the complexities of underlying thread.

Below are some benefits:

  1. Executor service manage thread in asynchronous way
  2. Use Future to get the return result after thread completion.
  3. Manage allocation of work to free thread and resale completed work from thread for assigning new work automatically
  4. fork – join framework for parallel processing
  5. Better communication between threads
  6. invokeAll and invokeAny give more control to run any or all thread at once
  7. shutdown provide capability for completion of all thread assigned work
  8. Scheduled Executor Services provide methods for producing repeating invocations of runnables and callables Hope it will help you

What is Future?
The Future interface represents the result of an asynchronous computation.It provides methods to check if the computation is complete, wait for the result, and retrieve the result

What is difference between calling submit and execute in executorService?
execute: Use it for fire and forget calls
submit: Method submit extends base method Executor.execute(Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. In nutshell submit is wrapper around execute

void execute(Runnable command) : Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.

submit could take both Runnable and Callable as argument

submit(Callable task) : Submits a value-returning task for execution and returns a Future representing the pending results of the task.
Future submit(Runnable task) : Submits a Runnable task for execution and returns a Future representing that task.

submit() is wrapper around execute and hides exception in the framework itself unless you embed your task code in try{} catch{} block.

execute() throws output when Runnable code actually throws exeception

public class Main {
    public static void main(String[] args) throws Exception {
        ExecutorService objExecService = Executors.newFixedThreadPool(2);

        objExecService.execute(new Runnable() {
            @Override
            public void run() {
                int num = 5/0;
                System.out.println("Division by zero successful");
            }
        });

        objExecService.shutdown();
    }
}

Output

Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
	at Main$1.run(Main.java:13)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:832)

submit() throws output when Runnable code actually throws exeception

public class Main {
    public static void main(String[] args) throws Exception {
        ExecutorService objExecService = Executors.newFixedThreadPool(2);

        objExecService.submit(new Runnable() {
            @Override
            public void run() {
                int num = 5/0;
                System.out.println("Division by zero successful");
            }
        });

        objExecService.shutdown();
    }
}

Output


Why thread pools are needed? Refer here
Thread objects use a significant amount of memory, and in a large-scale application, allocating and deallocating many thread objects creates a significant memory management overhead.Thread pool is a pool of already created worker thread ready to do the job. It creates Thread and manage them. Instead of creating Thread and discarding them once task is done, thread-pool reuses threads in form of worker thread.

Because creation of Thread is time consuming process and it delays request processing.

Threadpool addresses below issues.

  • Run time latency for thread creation
  • Uncontrolled use of System Resources

What is Executor? What are different ways of Creating Thread using Executors?
It provides a way to separate the task execution logic from the application code, allowing developers to focus on business logic rather than thread management.

The Executor framework consists of two main components:

  1. Executor interface and the ExecutorService interface. The Executor interface defines a single method, execute(Runnable), which is used to submit tasks for execution.
  2. The ExecutorService interface extends the Executor interface and provides additional methods for managing the execution of tasks, such as the ability to submit callables and the ability to shut down the executor.

Executor framework also provides a static utility class called Executors ( similar to Collections) which provides several static factory method to create various type of Thread Pool implementation in Java e.g. fixed size thread pool, cached thread pool and scheduled thread pool.best way to get an executor is to use one of the static factory methods provided by the Executors utility class. Some of the available factory methods in Executors class are:

  1. static ExecutorService newCachedThreadPool() : Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
  2. static ExecutorService newFixedThreadPool(int numThreads) : Creates a thread pool that reuses a fixed number of threads.
  3. static ScheduledExecutorService newScheduledThreadPool(int numThreads) : Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
  4. newSingleThreadExecutor() : Creates an Executor that uses a single worker thread.

Executor framework is used for creating threadpool

 ExecutorService service = Executors.newFixedThreadPool(10);

Why we need shutdown in executor service?
shutdown() method does one thing: prevents clients to send more work to the executor service. This means all the existing tasks will still run to completion unless other actions are taken. This is true even for scheduled tasks, e.g., for a ScheduledExecutorService: new instances of the scheduled task won’t run. It also frees up any background thread resources.

shutdown() method provides graceful application shutdown Prevent your application to submit new tasks, and wait for all the existing tasks to complete before shutting down the JVM.

shutdown() vs shutdownNow()?
shutdown() – Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
shutdownNow() – Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.

What is Java Fork-Join pool
Fork-Join Pools allow you to break down a larger task into smaller subtasks that can be executed concurrently. This is particularly valuable for tasks that can be divided into independent parts, such as recursive algorithms, matrix multiplication, sorting, and searching.This framework is well-suited for tasks that follow a recursive structure. A task is divided into smaller tasks until it reaches the base case, at which point the results are computed.Fork-Join Pools employ work-stealing algorithms, enabling idle threads to ‘steal’ tasks from other threads’ task queues when they have completed their own work.

What is Reactor Pattern?
The Reactor pattern efficiently handles multiple concurrent service requests by dispatching them to appropriate event handlers using a single or a limited number of threads.The idea is that you create a lot of threads which don’t do anything at first. Instead, they “wait for work”. When work arrives (in the form of code), some kind of executor service (the reactor) identifies idle threads from the pool and assigns them work to do.Use when low-latency and high-throughput in server-side applications, making it an essential strategy for modern networking frameworks and web servers

What is Future?
If you have code that performs some long-time operations and only then returns the result Future is used. Future is a placeholder. It doesn’t contain any value as long as the new thread hasn’t finished its work.

Future<String> objFuture = objExecService.submit(() ->{
              Thread.sleep(3000);
              return Thread.currentThread().getName();
});
System.out.println(objFuture.get());

While the separate thread is calculating something, the main thread continues its work. And when you think it’s finally time the value has got calculated, you write future.get() and get the actual value. But be careful: this time if the value hasn’t yet been assigned and the future is still empty, the main thread will have to wait until it happens

What is Worker Thread?
The idea is that you create a lot of threads which don’t do anything at first. Instead, they “wait for work”. When work arrives (in the form of code), some kind of executor service (the reactor) identifies idle threads from the pool and assigns them work to do. Worker Thread makes sense when taking in terms of the reactor pattern, different types of events are run by the handler threads which is similar. A thread is not tied to a single event class but will run any number of different events as they occur.

What is Interprocess Communication?
Interprocess communication (IPC) is a set of programming interfaces that allow a programmer to coordinate activities among different program processes that can run concurrently in an operating system. This allows a program to handle many user requests at the same time. Since even a single user request may result in multiple processes running in the operating system on the user’s behalf, the processes need to communicate with each other. The IPC interfaces make this possible. Each IPC method has its own advantages and limitations so it is not unusual for a single program to use all of the IPC methods.

Java interprocess communication is based at the lowest level on turning state, requests, etc into sequences of bytes that can be sent as messages or as a stream to another Java process. You can do this work yourself, or you can use a variety of “middleware” technologies of various levels of complexity to abstract away the implementation details. Technologies that may be used include, Java object serialization, XML, JSON, RMI, CORBA, SOAP / “web services”, message queing, and so on.

Interprocess Communication vs Inter-Thread Communication?
The fundamental difference is that threads live in the same address spaces, but processes live in the different address spaces. This means that inter-thread communication is about passing references to objects and changing shared objects, but processes is about passing serialized copies of objects.In practice, Java interthread communication can be implemented as plain Java method calls on a shared object with appropriate synchronization thrown in.

Inter-Thread Communication = threads inside the same JVM talking to each other.Threads inside the same JVM can use pipelining through lock-free queues to talk to each other with nanosecond latency.

Inter-Process Communication (IPC) = threads inside the same machine but running in different JVMs talking to each other.Threads in different JVMs can use off-heap shared memory (usually acquired through the same memory-mapped file) to talk to each other with nanosecond latency.

What is Starvation?
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. This happens when shared resources are made unavailable for long periods by “greedy” threads. For example, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.

What is Livelock?
A thread often acts in response to the action of another thread. If the other thread’s action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They’re still blocking each other, so…

Preemptive vs Non-Preemptive Scheduling
Scheduling is order of executuion of threads. JVM would simply use the underlying threading mechanism provided by the OS.
Non-preemptive Scheduling: The current process releases the CPU either by terminating or by switching to the waiting state. (Used in MS Windows family)

Advantages are Decreases turnaround time and Does not require special HW (e.g., timer)
Disadvantages are Limited choice of scheduling algorithm

Preemptive Scheduling: The current process needs to involuntarily release the CPU when a more important process is inserted into the ready queue or once an allocated CPU time has elapsed. (Used in Unix and Unix-like systems).This is determined by priority assigned to thread.Despite priority JVM may decide to execute thread of lower priority inorder to avoid starvation.

Advantages are No limitation on the choice of scheduling algorithm
Disadvantages are Additional overheads (e.g., more frequent context switching, HW timer, coordinated access to data, etc.)

How do you implement Thread in Java?
By extending java.lang.Thread class
By implementing java.lang.Runnable interface.

Which way of implementing Thread is better? Extending Thread class or implementing Runnable method?
Implementing Runnable is better because in Java we can only extend one class so if we extend Thread class we can not extend any other class while by implementing Runnable interface we still have that option open with us

What is the difference between start() and run() method of Thread class?
start() method is used to start newly created thread, while start() internally calls run() method

When you invoke run() as normal method, its called in the same thread, no new thread is started

Supplier Accounts.java

@FunctionalInterface
public interface Accounts{
  abstract String showAccountType(); 
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  //Implementation of Custom Supplier Method for Accounts Interface 
  Accounts squareRoot = () -> "Hi there";
  System.out.println(squareRoot.showAccountType());
 }
}

The above code could be expanded as below using Anonymous Inner Class

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType() {
    return "Hi there";
   }
  };
  System.out.println(squareRoot.showAccountType());
 }
}
Consumer Accounts.java

@FunctionalInterface
public interface Accounts {
 abstract void showAccountType(String strAccType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  //Implementation of Custom Consumer Method for Accounts Interface
  Accounts squareRoot = (strAccType) -> System.out.println(strAccType);
  squareRoot.showAccountType("Savings");
 }
}

The above code could be expanded as below using Anonymous Inner Class

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public void showAccountType(String strAccType) {
    System.out.println(strAccType);
   }
  };
 }
}
Predicate Accounts.java

@FunctionalInterface
public interface Accounts{
  abstract boolean showAccountType(String accountType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  //Implementation of Custom Predicate Method for Accounts Interface
  Accounts squareRoot = (accountType) -> {
   if ("Savings" == accountType)
    return true;
   else
    return false;
  };

  if (squareRoot.showAccountType("Savings"))
   System.out.println("Savings");
  else
   System.out.println("Invalid Account");
 }
}

The above code could be expanded as below using Anonymous Inner Class

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public boolean showAccountType(String accountType) {
    if ("Savings" == accountType)
     return true;
    else
     return false;
   }
  };

  if (squareRoot.showAccountType("Savings"))
   System.out.println("Savings");
  else
   System.out.println("Invalid Account");   
 }
}
Function Accounts.java

@FunctionalInterface
public interface Accounts  
{
 abstract String showAccountType(String accountType, String returnAccType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  //Implementation of Custom Function Method for Accounts Interface
  Accounts squareRoot = (accountType, returnType) -> {
   if (accountType == "Savings")
    return "Credit";
   else
    return "Debit";
  };

  System.out.println(squareRoot.showAccountType("Savings", null));
 }
}

The above code could be expanded as below using Anonymous Inner Class

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType(String accountType, String returnAccType) {

    if (accountType == "Savings")
     return "Credit";
    else
     return "Debit";
   }
  };

  System.out.println(squareRoot.showAccountType("Savings", null));
 }
}
Urnary Operator Accounts.java

@FunctionalInterface
public interface Accounts{
 abstract String showAccountType(String accountType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  //Implementation of Custom Operator Method for Accounts Interface
  Accounts squareRoot = (accountType) -> {
   return "AccountType is " + accountType;
  };
  squareRoot.showAccountType("Savings");
 }
}

The above code could be expanded as below using Anonymous Inner Class

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType(String accountType) {
    return "AccountType is " + accountType;
   }
  };

  System.out.println(squareRoot.showAccountType("Savings"));
 }
}
  1. Optional is a wrapper class which makes a field optional which means it may or may not have values.
  2. ptional as a single-value container that either contains a value or doesn’t (it is then said to be “empty”)
  3. The advantage compared to null references is that the Optional class forces you to think about the case when the value is not present. As a consequence, you can prevent unintended null pointer exceptions.
  4. The intention of the Optional class is not to replace every single null reference. Instead, its purpose is to help design more-comprehensible APIs so that by just reading the signature of a method, you can tell whether you can expect an optional value. This forces you to actively unwrap an Optional to deal with the absence of a value.

Lets take the below code

String version = computer.getSoundcard().getUSB().getVersion();

In the above piece of java code if any of the 3 values other the Version is NULL will throw a null pointer exception. To prevent this lets add a null check

String version = "UNKNOWN";
if(computer != null){
  Soundcard soundcard = computer.getSoundcard();
  if(soundcard != null){
    USB usb = soundcard.getUSB();
    if(usb != null){
      version = usb.getVersion();
    }
  }
}

Now the above code has become Clumsy with less readability and lot of boilerplate code has been added.
In languages like Groovy these conditions could be handles like one below

String version = computer?.getSoundcard()?.getUSB()?.getVersion();
(or)
String version = 
    computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";

Now lets replace the above code with new Optional in Java 8

public class Computer {
  private Optional<Soundcard> soundcard;  
  public Optional<Soundcard> getSoundcard() { ... }
  ...
}

public class Soundcard {
  private Optional<USB> usb;
  public Optional<USB> getUSB() { ... }

}

public class USB{
  public String getVersion(){ ... }
}

The advantage compared to null references is that the Optional class forces you to think about the case when the value is not present. As a consequence, you can prevent unintended null pointer exceptions.

What is the Point of Optional when the same could be done using NULL Check?
If you are doing NULL check the traditional way there would be no much difference. However, the difference is felt when you are carrying out chaining operations in streams and the datatypes returned are optional.The difference may not be significant in this case but as the chain of objects increases e.g. person.getAddress.getCity().getStreet().getBlock(),

Methods in Optional
get()
If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException

void ifPresent(Consumer consumer)
If a value is present, it invokes the specified consumer with the value, otherwise does nothing.

boolean isPresent()
Returns true if there is a value present, otherwise false.

static Optional ofNullable(T value)
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.

T orElse(T other)
Returns the value if present, otherwise returns other.

T orElseGet(Supplier other)
Returns the value if present, otherwise invokes other and returns the result of that invocation.

orElseThrow(Supplier exceptionSupplier)
Returns the contained value, if present, otherwise throws an exception to be created by the provided supplier.

Lets take a simple example where Optional returns Empty or Value based on some Condition

package com.example.demo;
import java.util.Optional;
public class Test {

 public static void main(String[] args) {
  //IfPresent
  Optional < String > strOpt = getName(" Piggy");
  System.out.print("First Call -");
  strOpt.ifPresent(System.out::println);


  Optional < String > strOpt2 = getName("");
  System.out.print("Second Call -");
  strOpt2.ifPresent(System.out::println);

  System.out.println();

  //IsPresent and get
  Optional < String > strOpt3 = getNewName(" Biggy");
  System.out.print("Third Call -");

  if (strOpt3.isPresent())
   System.out.println(strOpt3.get());


  //orElse
  Optional < String > strOpt4 = getNewName(null);
  System.out.print("Fourth Call -");
  System.out.println(strOpt4.orElse(" Hippi"));


 }

 public static Optional < String > getName(String strName) {
  if (strName.length() > 0)
   return Optional.of(strName);
  else
   return Optional.empty();
 }

 public static Optional < String > getNewName(String strName) {
  //Optional strNewName = (strName!=null)?Optional.of(strName):Optional.empty();
  return Optional.ofNullable(strName);
 }
}

Output

First Call - Piggy
Second Call -
Third Call - Biggy
Fourth Call - Hippi

A Bean definition contains the following piece of information called configuration metadata, which helps the container know the following things.

• The way a bean should be created.
• Life cycle details of a bean.
• Associated Bean dependencies.

The above metadata for the bean configuration is provided as a set of properties or attributes in an XML file (configuration file) which together prepare a bean definition. The following are the set of properties.

Properties Usage
class In a bean definition, it is a mandatory attribute. It is used to specify the bean class which can be used by the container to create the bean.
name In a bean definition, this attribute is used to specify the bean identifier uniquely. In XML based configuration metadata for a bean, we use the id and/or name attributes in order to specify the bean identifier(s).
scope This attribute is used to specify the scope of the objects which are created from a particular bean definition.
constructor-arg In a bean definition, this attribute is used to inject the dependencies.
properties In a bean definition, this attribute is used to inject the dependencies.
autowiring mode In a bean definition, this attribute is used to inject the dependencies.
lazy-initialization mode In a bean definition, a lazy-initialized bean informs the IoC container to create a bean instance only when it is first requested, instead of startup.
initialization method In a bean definition, a callback to be called after all required properties on the bean have been set up by the container.
destruction method In a bean definition, a callback to be used when the container that contains the bean is destroyed.

In the following example, we are going to look into an XML based configuration file which has different bean definitions. The definitions include lazy initialization (lazy-init), initialization method (init-method), and destruction method (destroy-method) as shown below. This configuration metadata file can be loaded either through BeanFactory or ApplicationContext

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- A simple bean definition -->
   <bean id = "..." class = "...">
      <!— Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has lazy init set on -->
   <bean id = "..." class = "..." lazy-init = "true">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has initialization method -->
   <bean id = "..." class = "..." init-method = "...">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has destruction method -->
   <bean id = "..." class = "..." destroy-method = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- more bean definitions can be written below -->
   
</beans>

Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

3 types of method references:

  1. Reference to a static method
  2. Reference to an instance method
  3. Reference to a constructor

Reference to a static method
Syntax

  ClassName::MethodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public static int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  BiFunction < Integer, Integer, Integer > adder = Arithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to an instance method
Syntax

Object::methodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  Arithmetic objArithmetic = new Arithmetic();
  BiFunction < Integer, Integer, Integer > adder = objArithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to a constructor
Syntax

ClassName::new  
interface Messageable {
 Message getMessage(String msg);
}
class Message {
 Message(String msg) {
  System.out.print(msg);
 }
}
public class ConstructorReference {
 public static void main(String[] args) {
  Messageable hello = Message::new;
  hello.getMessage("Hello");
 }
}

Q1.What is the Difference between applicationContext and BeanFactory?
ApplicationContext is more feature rich container implementation and should be favored over BeanFactory.Both BeanFactory and ApplicationContext provides a way to get a bean from Spring IOC container by calling getBean(“bean name”)

  1. Bean factory instantiate bean when you call getBean() method while ApplicationContext instantiates Singleton bean when the container is started, It doesn’t wait for getBean to be called.
  2. BeanFactory provides basic IOC and DI features while ApplicationContext provides advanced features
  3. ApplicationContext is ability to publish event to beans that are registered as listener.
  4. implementation of BeanFactory interface is XMLBeanFactory while one of the popular implementation of ApplicationContext interface is ClassPathXmlApplicationContext.In web application we use we use WebApplicationContext which extends ApplicationContext interface and adds getServletContext method
  5. ApplicationContext provides Bean instantiation/wiring,Automatic BeanPostProcessor registration, Automatic BeanFactoryPostProcessor registration,Convenient MessageSource access and ApplicationEvent publication whereas BeanFactory provides only Bean instantiation/wiring

null

Q2.What is the Difference between Component and Bean?

  1. @Component auto detects and configures the beans using classpath scanning whereas @Bean explicitly declares a single bean, rather than letting Spring do it automatically.
  2. @Component does not decouple the declaration of the bean from the class definition where as @Bean decouples the declaration of the bean from the class definition.
  3. @Component is a class level annotation where as @Bean is a method level annotation and name of the method serves as the bean name.
  4. @Component need not to be used with the @Configuration annotation where as @Bean annotation has to be used within the class which is annotated with @Configuration.
  5. We cannot create a bean of a class using @Component, if the class is outside spring container whereas we can create a bean of a class using @Bean even if the class is present outside the spring container.
  6. @Component has different specializations like @Controller, @Repository and @Service whereas @Bean has no specializations.

@Component (and @Service and @Repository) are used to auto-detect and auto-configure beans using classpath scanning. There’s an implicit one-to-one mapping between the annotated class and the bean (i.e. one bean per class). Control of wiring is quite limited with this approach since it’s purely declarative.

@Bean is used to explicitly declare a single bean, rather than letting Spring do it automatically as above. It decouples the declaration of the bean from the class definition and lets you create and configure beans exactly how you choose.

Let’s imagine that you want to wire components from 3rd-party libraries (you don’t have the source code so you can’t annotate its classes with @Component), where an automatic configuration is not possible.The @Bean annotation returns an object that spring should register as a bean in the application context. The body of the method bears the logic responsible for creating the instance.
@Bean is applicable to methods, whereas @Component is applicable to types

Q3.What is the difference between @Configuration and @Component in Spring?
@Configuration Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime

@Component Indicates that an annotated class is a “component”. Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.

@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning

Q4.Life cycle of Spring Bean

  1. There are five methods called before bean comes to ready state
  2. BeanPostProcessor method – postProcessBeforeInitilaization and postProcessAfterInitilaization would be called between init method(3 methods)
  3. After postProcessBeforeInitilaization @postContruct and afterPropertiesSet method would be called(2 methods)
  4. Bean comes to Ready state
  5. Once Spring shutdown is called @PreDestroy, destroy() and custom destroy method are called(3 methods)

Refer here

Q5.What is CGLIB in Spring?
Classes in Java are loaded dynamically at runtime. Cglib is using this feature of Java language to make it possible to add new classes to an already running Java program.Hibernate uses cglib for generation of dynamic proxies. For example, it will not return full object stored in a database but it will return an instrumented version of stored class that lazily loads values from the database on demand.Popular mocking frameworks, like Mockito, use cglib for mocking methods. The mock is an instrumented class where methods are replaced by empty implementations.

Q6.What is the difference between applicationcontext and webapplicationcontext in Spring?

  1. Spring MVC has ApplicationContext and WebApplicationContexts which is the extension of ApplicationContext
  2. There could be more than one WebApplicationContext
  3. All the Stateless attributes like DBConnections and Spring Security would be defined in ApplicationContext and shared among multiple WebApplicationContext
  4. ApplicationContext are loaded by ContextLoaderListener which is declared in web.xml
  5. A single web application can have multiple WebApplicationContext and each Dispatcher servlet (which is the front controller of Spring MVC architecture) is associated with a WebApplicationContext. The webApplicationContext configuration file *-servlet.xml is specific to a DispatcherServlet. And since a web application can have more than one dispatcher servlet configured to serve multiple requests, there can be more than one webApplicationContext file per web application.

Refer here

Q7.What are different bean scopes with realtime example?
Singleton: It returns a single bean instance per Spring IoC container.This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object. If no bean scope is specified in the configuration file, singleton is default. Real world example: connection to a database

Prototype: It returns a new bean instance each time it is requested. It does not store any cache version like singleton. Real world example: declare configured form elements (a textbox configured to validate names, e-mail addresses for example) and get “living” instances of them for every form being created.Batch processing of data involves prototype scope beans.

Request: It returns a single bean instance per HTTP request. Real world example: information that should only be valid on one page like the result of a search or the confirmation of an order. The bean will be valid until the page is reloaded.

Session: It returns a single bean instance per HTTP session (User level session). Real world example: to hold authentication information getting invalidated when the session is closed (by timeout or logout). You can store other user information that you don’t want to reload with every request here as well.

GlobalSession: It returns a single bean instance per global HTTP session. It is only valid in the context of a web-aware Spring ApplicationContext (Application level session). It is similar to the Session scope and really only makes sense in the context of portlet-based web applications. The portlet specification defines the notion of a global Session that is shared among all of the various portlets that make up a single portlet web application. Beans defined at the global session scope are bound to the lifetime of the global portlet Session.

Q8.What is Portlet application?what is the difference between a portlet and a servlet?
Servlets and Portlets are web based components which use Java for their implementation.Portlets are managed by a portlet container just like servlet is managed by servlet container.
When your application works in Portlet container it is built of some amount of portlets. Each portlet has its own session, but if your want to store variables global for all portlets in your application than you should store them in globalSession. This scope doesn’t have any special effect different from session scope in Servlet based applications.

The simplest way to think of this is that a servlet renders an entire web page, and a portlet renders a specific rectangular part (subsection) of a web page. For example, the advertising bar on the right hand side of a news page could be rendered as a portlet. But you wouldn’t implement a single edit field as a portlet, because that’s too granular. Basically if you break down a web page into it’s major sectional areas, those are good candidates to make into portlets. Portlet never renders complete web page with html start and end tags but part of page.

Spring Bean life Cycle is hooked to the below 4 interfaces Methods

  1. InitializingBean and DisposableBean callback interfaces
  2. *Aware interfaces for specific behavior
  3. Custom init() and destroy() methods in bean configuration file
  4. @PostConstruct and @PreDestroy annotations

null

InitializingBean and DisposableBean callback interfaces
InitializingBean and DisposableBean are two marker interfaces, a useful way for Spring to perform certain actions upon bean initialization and destruction.

  1. For bean implemented InitializingBean, it will run afterPropertiesSet() after all bean properties have been set.
  2. For bean implemented DisposableBean, it will run destroy() after Spring container is released the bean.

Refer Here and here

Custom init() and destroy() methods in bean configuration file
Using init-method and destroy-method as attribute in bean configuration file for bean to perform certain actions upon initialization and destruction.

@PostConstruct and @PreDestroy annotations
We can manage lifecycle of a bean by using method-level annotations @PostConstruct and @PreDestroy.

The @PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.

The @PreDestroy annotation is used on methods as a callback notification to signal that the instance is in the process of being removed by the container.

@PostConstruct vs init-method vs afterPropertiesSet
There is any difference but there are priorities in the way they work. @PostConstruct, init-method.@PostConstruct is a JSR-250 annotation while init-method is Spring’s way of having an initializing method.If you have a @PostConstruct method, this will be called first before the initializing methods are called. If your bean implements InitializingBean and overrides afterPropertiesSet, first @PostConstruct is called, then the afterPropertiesSet and then init-method.

@Component
public class MyComponent implements InitializingBean {
	
	@Value("${mycomponent.value:Magic}")
	public String value;
	
	public MyComponent() {
		log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null [properties not set yet]
	}
	
	@PostConstruct
	public void postConstruct() {
		log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
	}

	@Override // (equivalent to init-method in XML; overrides InitializingBean.afterPropertiesSet()
	public void afterPropertiesSet() {
		log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
	}	

        public void initIt() throws Exception {
	  log.info("MyComponent in init: " + value);
	}

	@PreDestroy
	public void preDestroy() {
		log.info("MyComponent in preDestroy: [{}], self=[{}]", value); // (3) displays: 
	}

        public void cleanUp() throws Exception {
	  log.info("Spring Container is destroy! Customer clean up");
	}
}

Spring.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<bean id="customerService" class="com.mkyong.customer.services.CustomerService" 
		init-method="initIt" destroy-method="cleanUp">   		
		<property name="message" value="i'm property message" />
	</bean>		
</beans>

Output

MyComponent in constructor: [null]
MyComponent in postConstruct: [Magic]
MyComponent in init: [Magic from XML]
MyComponent in afterPropertiesSet: [Magic]
MyComponent in preDestroy: [Magic]
Spring Container is destroy! Customer clean up

When to use what?
init-method and destroy-method is the recommended approach because of no direct dependency to Spring Framework and we can create our own methods.
InitializingBean and DisposableBean To interact with the container’s management of the bean lifecycle, you can implement the Spring InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the former and destroy() for the latter to allow the bean to perform certain actions upon initialization and destruction of your beans.
@PostConstruct and @PreDestroy – The JSR-250 @PostConstruct and @PreDestroy annotations are generally considered best practice for receiving lifecycle callbacks in a modern Spring application. Using these annotations means that your beans are not coupled to Spring specific interfaces.

What are different ways to create Bean in Spring Boot?

  1. Using @Component over class – To create app specific bean
  2. Using @Configuration over class and @Bean over method – To create bean from third party class added as JAR dependency. You cannot add component in added JAR class files.

What is Dependency Injection?
Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself.

What are Types of Dependency Injection?

  1. Constructor Injection – Dependency provided as parameter to constructor. This ensures Object is fully initialized upon creation and promoting immutability
  2. Setter Injection – Setter injection is having independent setter for each class attributes and calling setter method while initializing. Setter Injection allow more flexibility by allowing dependencies to be set or changed after object creation.
  3. Field Injection – Field injection is old method of injecting dependencies by specifying the @Autowired over field name. It works based on Java reflection and it is not recommended as it makes code more difficult to test

What are Stereotype Annotations?

Stereotype – idea of a particular type of person or thing.

Spring comes with 4 Stereotype annotations as below.

@Component is a generic stereotype for any Spring-managed component. @Repository, @Service, @Controller are specializations of @Component for more specific use cases (in the persistence, service, and presentation layers, respectively).

  1. @Component general-purpose stereotype annotation indicating that the class is a spring component.
  2. @Controller @Controller annotation indicates that a particular class serves the role of a controller. The dispatcher scans the classes annotated with @Controller and detects methods annotated with @RequestMapping annotations within them. We can use @RequestMapping on/in only those methods whose classes are annotated with @Controller
  3. @Repository
  4. stereotype for persistence layer. @Repository’s job is to catch platform specific exceptions and re-throw them as one of Spring’s unified unchecked exception. By masking the platform specific exception to spring unified exception it helps 1.Providing higher level of Abstraction for User 2.By throwing unchecked exception it prevents user from adding unnecessary boiler plate for exception handling by means of try catch blocks

  5. @Service – @Service beans hold the business logic and call methods in the repository layer.

Note : Spring may add special functionalities for @Service, @Controller and @Repository based on their layering conventions.

How it is internally is all 3 are marked with @Component.@CompnentScan only scans @Component and does not look for @Controller, @Service and @Repository in general. They are scanned because they themselves are annotated with @Component.

@Component
public @interface Service {
    ….
}

@Component
public @interface Repository {
    ….
}

@Component
public @interface Controller {
    …
}

What happens when more than one bean of same type is found? What would be workaround?
Application would fail to start with error message Require Single bean but N beans found.

This could be addressed in two ways

  1. Using @Qualifier annotation
  2. Using @Primary annotation

@Qualifier annotation takes bean Id as value to uniquely identify a bean.

StudentController.java

public class StudentController{
 .
 @Autowired
 public StudentController(@Qualifier("student") Person person){
 .
 }
}

Student.java

@Component
public class Student implements Person{
.
}

@Primary annotation works by giving first preference to bean which is marked with @Primary annotation. If two beans are marked with @Primary annotation then Spring boot throws an error. If both @Primary and @Qualifier annotation is used, then @Qualifier annotation takes preference.

@Primary vs @Qualifier Which one takes precedence?
@Qualifier takes precedence over @Primary annotation.

What does @Lazy annotation do?
Unlike the bean which are marked with @Component are loaded at startup when the app start, @Lazy annotation does the bean loading only when it is needed.

This can be Configured globally as well by specifying in application.properties as below. If your application has lot of components and because of this the app takes long time to start then its better to use this.

application.properties

spring.main.lazy-initialization=true

Note: If you use @Lazy annotation along with @Restcontroller it may lead to timeout issues.

Report.java

public interface Report {
    String generateReport();
}

PDFReport.java

@Primary
@Component
public class PDFReport implements Report{
    public PDFReport() {
        System.out.println("Loaded PDFReport");
    }

    @Override
    public String generateReport() {
        return "PDF Report";
    }
}

excelReport.java

@Component
public class excelReport implements Report{
    public excelReport() {
        System.out.println("Loading Excel Report");
    }

    @Override
    public String generateReport() {
        return "Excel Report";
    }
}

textReport.java

@Component
@Lazy
public class textReport implements Report{
    public textReport() {
        System.out.println("Loading textReport Report");
    }
    @Override
    public String generateReport() {
        return "Text Report";
    }
}

GenerateReport.java

@RestController
public class GenerateReport {
    private Report report;

    public GenerateReport(@Qualifier("excelReport") Report report){
        this.report = report;
    }

    @GetMapping("/generateReport")
    public String generateReport(){
        return "Printing report in "+ report.generateReport() + " format";
    }
}

Excel Report format would be printed as @Qualifier would take precedence
Output in Browser(http://localhost:8080/generateReport)

Loading Excel Report
Loaded PDFReport

Printing report in Excel Report format

What are different Bean Scopes?
Singleton – Only one bean for Container, served same bean for every access
Prototype – New bean for every access
Request – New bean for every request
Session – Only one bean for Session
Application – Only one bean for Application
Websocket

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Checking Object based on Bean Scope – Singleton
excelReport bean with Singleton scope returning same bean every access
excelReport.java

@Component
public class excelReport implements Report{
.
.
}

GenerateReport.java

@RestController
public class GenerateReport {
    private Report report1;
    private Report report2;

    public GenerateReport(@Qualifier("excelReport") Report report1, @Qualifier("excelReport") Report report2){
        this.report1 = report1;
        this.report2 = report2;
    }

    @GetMapping("/checkBean")
    public String checkBean(){
        if(report1 == report2){
            return "Bean are Same";
        }else{
            return  "Bean are Different";
        }
    }
}

Output(http://localhost:8080/checkBean)

Bean are Same

Checking Object based on Bean Scope – Prototype
pdfReport bean with Prototype scope returning different bean on every access
PDFReport.java

@Primary
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PDFReport implements Report{
  .
  .
}

GenerateReport.java

@RestController
public class GenerateReport {
    private Report report1;
    private Report report2;

    public GenerateReport(Report report1, Report report2){
        this.report1 = report1;
        this.report2 = report2;
    }

    @GetMapping("/checkBean")
    public String checkBean(){
        if(report1 == report2){
            return "Bean are Same";
        }else{
            return  "Bean are Different";
        }
    }
}

Output(http://localhost:8080/checkBean)

Bean are Different

How to inject bean created using new Operator or Injecting Spring beans into non-managed objects
Objects for 3rd party JAR are created using @Configuration at class level and using @Bean at method level. This is one other way to create bean other than @Component as
we wont be able to change the source of 3rd party class files.

  1. Using @Configuration and @Bean annotation
  2. Using @Configurable refer here
  3. using AutowireCapableBeanFactory

Let take the below code

public class MyBean 
{
    @Autowired 
    private AnotherBean anotherBean;
}

MyBean obj = new MyBean();

I have a class doStuff in which the obj of MyBean created using new operator needs to be injected. To do this use AutowireCapableBeanFactory and call autowireBean method with beanFactory reference.

private @Autowired AutowireCapableBeanFactory beanFactory;

public void doStuff() {
   MyBean obj = new MyBean();
   beanFactory.autowireBean(obj);
   //obj will now have its dependencies autowired.
}

What is the Difference between @Inject and @Autowired in Spring Framework?
@Inject specified in javax.inject.Inject annotations is part of the Java CDI (Contexts and Dependency Injection) standard introduced in Java EE 6 (JSR-299). Spring has chosen to support using @Inject synonymously with their own @Autowired annotation.@Autowired is Spring’s own (legacy) annotation. @Inject is part of a new Java technology called CDI that defines a standard for dependency injection similar to Spring. In a Spring application, the two annotations work the same way as Spring has decided to support some JSR-299 annotations in addition to their own.

Use of the Following in Spring Framework?
@RequestMapping – All incoming requests are handled by the Dispatcher Servlet and it routes them through the Spring framework. When the Dispatcher Servlet receives a web request, it determines which controllers should handle the incoming request. Dispatcher Servlet initially scans all the classes that are annotated with the @Controller annotation. The dispatching process depends on the various @RequestMapping annotations declared in a controller class and its handler methods.The @RequestMapping annotation is used to map the web request onto a handler class (i.e. Controller) or a handler method and it can be used at the Method Level or the Class Level.

Example – for the URL http://localhost:8080/ProjectName/countryController/countries

@Controller
@RequestMapping(value = "/countryController")
public class CountryController {
 
 @RequestMapping(value = "/countries", method = RequestMethod.GET, headers = "Accept=application/json")
 public List getCountries() {
    // Some Business Logic
 } 
Annotations Equivalent
@GetMapping @RequestMapping(method = RequestMethod.GET)
@PostMapping @RequestMapping(method = RequestMethod.POST)
@PutMapping @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping @RequestMapping(method = RequestMethod.DELETE)
@PatchMapping @RequestMapping(method = RequestMethod.PATCH)

@RequestParam – By using RequestParam we can get parameters to the method

@RequestMapping(value = "/display", method = RequestMethod.GET)
public String showEmployeeForm(@RequestParam("empId") String empId) {
        // Some Business Logic
}

@Pathvariable – @PathVariable is to obtain some placeholder from the URI
If empId and empName as parameters to the method showEmployeeForm() by using the @PathVariable annotation. For e.g.: /employee/display/101/Mux
empId = 101
empName = Mux

@Controller
@RequestMapping(value = "/employee")
public class EmployeeController {
    @RequestMapping(value = "/display/{empId}/{empName}")
    public ModelAndView showEmployeeForm(@PathVariable String empId, @PathVariable String empName) {
                // Some Business Logic
    } 
}

What is the Difference between @RequestParam vs @PathVariable?
@RequestParam annotation has following attributes

http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
public String getDetails(
    @RequestParam(value="param1", required=true) String strParam1,
        @RequestParam(value="param2", required=false,  defaultValue = "John") String strParam2){
...
}

@PathVariable is always considered required and cannot be null whereas @RequestParam could be null

@RequestParam annotation can specify default values if a query parameter is not present or empty by using a default Value attribute, provided the required attribute is false. . If a corresponding path segment is missing, Spring will result in a 404 Not Found error.

defaultValue This is the default value as a fallback mechanism if request is not having the value or it is empty. i.e param1
name Name of the parameter to bind i.e param1
required Whether the parameter is mandatory or not. If it is true, failing to send that parameter will fail. i.e false
value This is an alias for the name attribute i.e param1

@PathVariable is to obtain some placeholder from the URI (Spring call it an URI Template) and @RequestParam is to obtain an parameter from the URI as well.@PathVariable annotation has only one attribute value for binding the request URI template. It is allowed to use the multiple @PathVariable annotation in the single method. But, ensure that no more than one method has the same pattern.Annotation which indicates that a method parameter should be bound to a name-value pair within a path segment. Supported for RequestMapping annotated handler methods.

localhost:8080/person/Tom;age=25;height=175 and Controller:
@GetMapping("/person/{name}")
@ResponseBody
public String person(
    @PathVariable("name") String name, 
    @MatrixVariable("age") int age,
    @MatrixVariable("height") int height) {

    // ...
}

How Spring will decide bean if there are multiple implementation of Same Instance?

In such case it would fail at start telling expected 1 bean but found n bean

We can use @Qualifier annotation where we can decide the bean to be loaded based on the beanId. beanId is always the component name with camel casing

public class GenerateReport {
    private Report report1;
    private Report report2;

    public GenerateReport(@Qualifier("excelReport") Report report1, Report report2){
        this.report1 = report1;
        this.report2 = report2;
    }
}

What BeanLife cycle methods are available?

@PostConstruct and @PreDestroy

@Component
public class excelReport implements Report{
    public excelReport() {
        System.out.println("Loading Excel Report");
    }

    @Override
    public String generateReport() {
        return "Excel Report";
    }

    @PreDestroy
    public void doCleanUpStuff(){
        System.out.println("Disposing ExcelReport....: Prints when Server Stops");
    }

    @PostConstruct
    public void doStartUpStuff(){
        System.out.println("Completed Initialization ExcelReport...: Prints when Server Starts");
    }
}

Output – When Server Starts

Completed Initialization ExcelReport...: Prints when Server Starts

Output – When Server Stops

Disposing ExcelReport....: Prints when Server Stops

What is use of @RequestBody and @ResponseBody?

  1. @RequestBody and @ResponseBody used in controller to implement smart object serialization and deserialization. They help you avoid boilerplate code by extracting the logic of message conversion and making it an aspect. Other than that they help you support multiple formats for a single REST resource without duplication of code.
  2. If you annotate a method with @ResponseBody, spring will try to convert its return value and write it to the http response automatically.
  3. If you annotate a methods parameter with @RequestBody, spring will try to convert the content of the incoming request body to your parameter object on the fly.

What is @Transactional used for?
When Spring loads your bean definitions, and has been configured to look for @Transactional annotations, it will create these proxy objects around your actual bean. These proxy objects are instances of classes that are auto-generated at runtime. The default behaviour of these proxy objects when a method is invoked is just to invoke the same method on the “target” bean (i.e. your bean).
Refere here

@Configuration – @Configuration as a replacement to the XML based configuration for configuring spring beans.So instead of an xml file we write a class and annotate that with @Configuration and define the beans in it using @Bean annotation on the methods.It is just another way of configuration Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.

Use @Configuration annotation on top of any class to declare that this class provides one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.

AppConfig.java

@Configuration
public class AppConfig {
 
    @Bean(name="demoService")
    public DemoClass service()
    {
        
    }
}

pom.xml
The following dependency should be added to pom.xml before using @configuration annotation to get the bean from the context

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>
public class VerifySpringCoreFeature
{
    public static void main(String[] args)
    {
        ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); 
        DemoManager  obj = (DemoManager) context.getBean("demoService"); 
        System.out.println( obj.getServiceName() );
    }
}

What if I want to ensure the beans are already loaded even before requested and fail-fast

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MySpringApp {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();
		MyBean mb1 = ctx.getBean(MyBean.class);
		MyBean mb2 = ctx.getBean(MyBean.class);
		ctx.close();
	}
}

In the above example Spring loads beans into it’s context before we have even requested it. This is to make sure all the beans are properly configured and application fail-fast if something goes wrong.

Now what will happen if we uncomment the @Configuration annotation in the above class. In this case, if we make a call to myBean() method then it will be a plain java method call and we will get a new instance of MyBean and it won’t remain singleton.

@Configurble – How to inject dependencies into objects that are not created by Spring

public class CarSalon {
    //...
    public void testDrive() {
        Car car = new Car();
        car.startCar();
    }
}
 
@Component
public class Car {
    @Autowired
    private Engine engine;
    @Autowired
    private Transmission transmission;
 
    public void startCar() {
        transmission.setGear(1);
        engine.engineOn();
        System.out.println("Car started");
    }
}
 
@Component
public class Engine {
//...
}
 
@Component
public class Transmission {
//...
}

In the above example

  1. We try to create a Object for Car class using new operator
  2. How ever objects created using new operator are not container managed rather Java Runtime Managed
  3. Trying to access the startCar method using car object will throw NullPointerException
  4. However using @Configurable annotation will tell Spring to inject dependencies into the object before the constructor is run
  5. You need to have these JAR files in pom.xml inorder to make it work.aspectj-x.x.x.jar, aspectjrt.jar, aspectjveawer-x.x.x.jar
@Configurable(preConstruction = true)
@Component
public class Car {
 
    @Autowired
    private Engine engine;
    @Autowired
    private Transmission transmission;
 
    public void startCar() {
        transmission.setGear(1);
        engine.engineOn();
 
        System.out.println("Car started");
    }
}

Q1.What is use of @SpringBootApplication

 @SpringBootApplication =  @Configuration + @EnableAutoConfiguration + @ComponentScan

@Configuration – Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.Refer here

@EnableAutoConfiguration – @EnableAutoConfiguration automatically configures the Spring application based on its included jar files, it sets up defaults or helper based on dependencies in pom.xml. Auto-configuration is usually applied based on the classpath and the defined beans. Therefore, we donot need to define any of the DataSource, EntityManagerFactory, TransactionManager etc and magically based on the classpath, Spring Boot automatically creates proper beans and registers them for us. For example when there is a tomcat-embedded.jar on your classpath you likely need a TomcatEmbeddedServletContainerFactory (unless you have defined your own EmbeddedServletContainerFactory bean).

@EnableAutoConfiguration has a exclude attribute to disable an auto-configuration explicitly otherwise we can simply exclude it from the pom.xml, for example if we do not want Spring to configure the tomcat then exclude spring-bootstarter-tomcat from spring-boot-starter-web.
@ComponentScan – @ComponentScan provides scope for spring component scan, it simply goes though the provided base package and picks up dependencies required by @Bean or @Autowired etc, In a typical Spring application, @ComponentScan is used in a configuration classes, the ones annotated with @Configuration. Configuration classes contains methods annotated with @Bean. These @Bean annotated methods generate beans managed by Spring container. Those beans will be auto-detected by @ComponentScan annotation. There are some annotations which make beans auto-detectable like @Repository , @Service, @Controller, @Configuration, @Component. In below code Spring starts scanning from the package including BeanA class

@Configuration
@ComponentScan(basePackageClasses = BeanA.class)
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class Config {

  @Bean
  public BeanA beanA(){
    return new BeanA();
  }

  @Bean
  public BeanB beanB{
    return new BeanB();
  }

}

Q2.What @Configurable annotation Does?
@Configurable – @Configurable is an annotation that injects dependencies into objects, that are not managed by Spring using aspectj libraries. You still use old way of instantiation with plain new operator to create objects but the spring will take care of injecting the dependencies into that object automatically for you.
Refer here

Q3.What is Starter Project?What are the Starter Project offered?
Starter POMs are a set of convenient dependency descriptors that you can include in your application
spring-boot-starter-web-services – SOAP Web Services
spring-boot-starter-web – Web & RESTful applications
spring-boot-starter-test – Unit testing and Integration Testing
spring-boot-starter-jdbc – Traditional JDBC
spring-boot-starter-hateoas – Add HATEOAS features to your services
spring-boot-starter-security – Authentication and Authorization using Spring Security
spring-boot-starter-data-jpa – Spring Data JPA with Hibernate
spring-boot-starter-data-rest – Expose Simple REST Services using Spring Data REST

Q4.What SpringApplication.run() method does?

@SpringBootApplication
public class EmployeeManagementApplication 
{
 public static void main(String[] args) 
 {
  SpringApplication.run(EmployeeManagementApplication.class, args);
 }
}

– SpringApplication class is used to bootstrap and launch a Spring application from a Java main method.
– Creates the ApplicationContext from the classpath, scan the configuration classes and launch the application
– You can find the list of beans loaded by changing the code as below.Spring Boot provides auto-configuration, there are a lot of beans getting configured by it.

  
@SpringBootApplication(scanBasePackages = "com.mugil.org.beans")
public class EmployeeManagementApplication
{
	public static void main(String[] args)
	{
		ApplicationContext ctx = SpringApplication.run(EmployeeManagementApplication.class, args);
		String[] beans = ctx.getBeanDefinitionNames();
		for(String s : beans) System.out.println(s);
	}
}

@Component
public class Employee 
{
.
.
.
}

In the console you could see employeeManagementApplication and employee getting printed with their starting
letter in lower case.

Q5.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. 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 the basic configuration needed to configure the application with these frameworks. This is called Auto Configuration.

Q6.
Q7.