0% found this document useful (0 votes)
8 views31 pages

UNIT-2 Spring Board

Uploaded by

sreeranganadh008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views31 pages

UNIT-2 Spring Board

Uploaded by

sreeranganadh008
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 31

Spring Boot Autowiring

Till now we have been using XML for writing Spring configurations. Spring also supports
Annotations for configuration. And the best part is that, both of them can also co-exist in
the same project.

In Annotation based configuration, configuration is provided by using annotations on the


relevant property, method or the class.
Annotation based configuration reduces the amount of configuration required in the XML file by
using

 Autowiring: This supports autowiring dependencies using annotations such as


@Autowired and @Qualifier.

 Auto Scanning: This enable Spring to auto create beans of the required
classes and register with container for usage by eliminating the
explicit <bean> definitions in the XML file.

By default autowiring annotations is turned off. <context:annotation-config> tag has


to be specified in XML-based configuration to enable annotations support.
The XML configuration looks like as follows:

1. spring " context " namespace has "annotation-config" tag and hence
context namespace has to be included in the declaration

2. This will enable support for annotations


Spring Boot Application Annotation
Spring Boot is built on the top of the spring and contains all the features of
spring. The developers to directly focus on the logic instead of struggling
with the configuration and setup.

a microservice-based framework. It takes


Spring Boot is
very less time to develop an application.
Following are some of the features of Spring Boot:
 It avoids heavy configuration of XML which is present in spring
 It provides easy maintenance and creation of REST(Representation of
State Transfer) endpoints.
 It includes embedded Tomcat-server
 Deployment is very easy: war(WEB application archive or web application
resources) and jar(java ARchive) files can be easily deployed in the
tomcat server. (WAR and JAR files can be easily deployed)

Spring Annotations are a form of metadata. It provides data about a


program. Annotations. It does not change the action of the compiled
program.
org.springframework.boot.autoconfigure and org.springframework.boo
t.autoconfigure.condition packages are commonly known as Spring Boot
annotations.
Some of the annotations that are available in this category are:
 @SpringBootApplication
 @SpringBootConfiguration
 @EnableAutoConfiguration
 @ComponentScan
 Auto-Configuration Conditions
 @ConditionalOnClass, and @ConditionalOnMissingClass
 @ConditionalOnBean, and @ConditionalOnMissingBean
 @ConditionalOnProperty
 @ConditionalOnResource
 @ConditionalOnWebApplication and
@ConditionalOnNotWebApplication
 @ConditionalExpression
 @Conditional

1. @SpringBootApplication Annotation
This annotation is used to mark the main class of a Spring Boot
application. It encapsulates @SpringBootConfiguration,
@EnableAutoConfiguration, and @ComponentScan annotations
with their default attributes.

@SpringBootApplication
// Class
public class DemoApplication {
// Main driver method
public static void main(String[] args)
{
SpringApplication.run(DemoApplication.class, args);
}
}

2. @SpringBootConfiguration Annotation

It is a class-level annotation that is part of the Spring Boot framework.


It can be used as an alternative to Spring’s
standard @Configuration annotation so that configuration can be found
automatically. Most Spring Boot Applications use @SpringBootConfiguration
via @SpringBootApplication. If an application uses
@SpringBootApplication, it is already using
@SpringBootConfiguration.
@SpringBootConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public StudentService studentService() {
return new StudentServiceImpl();
}
}

3. @EnableAutoConfiguration Annotation
This annotation auto-configures the beans that are
present in the classpath. It simplifies the developer’s work by
assuming the required beans from the classpath and configure it to run the
application. This annotation is part of the spring boot framework.

For example, when we illustrate the spring-boot-starter-web dependency


in the classpath, Spring boot auto-configures Tomcat, and Spring MVC. The
package of the class declaring the @EnableAutoConfiguration annotation is
considered as the default. Therefore, we need to apply the
@EnableAutoConfiguration annotation in the root package so that every sub-
packages and class can be examined.

@Configuration

@EnableAutoConfiguration

public class Application {


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

4. @ComponentScan Annotation
@ComponentScan tells Spring in which packages you have annotated
classes that should be managed by Spring.

So, for example, if you have a class annotated with @Controller which is in a
package that is not scanned by Spring, you will not be able to use it as a
Spring controller.

So we can say @ComponentScan enables Spring to scan for things like


configurations, controllers, services, and other components that are defined.

Generally, @ComponentScan annotation is used with @Configuration


annotation to specify the package for Spring to scan for components.
@Configuration
@ComponentScan

// Main class
public class Application {

// Main driver method


public static void main(String[] args)
{

SpringApplication.run(Application.class, args);
}
}

5. @ConditionalOnClass Annotation and @ConditionalOnMissingClass


Annotation
@ConditionalOnClass Annotation used to mark auto-configuration bean if
the class in the annotation’s argument is present/absent .

@Configuration
@ConditionalOnClass(MongoDBService.class)

class MongoDBConfiguration {
// Insert code here
}

6. @ConditionalOnBean Annotation and @ConditionalOnMissingBean


Annotation
These annotations are used to let a bean be included based on the
presence or absence of specific beans.
@Bean
@ConditionalOnMissingBean(type = "JpaTransactionManager")
JpaTransactionManager jpaTransactionManager(
EntityManagerFactory entityManagerFactory)
{
// Insert code here
}

7. @ConditionalOnProperty Annotation
These annotations are used to let configuration be included based on the
presence and value of a Spring Environment property.
@Bean
@ConditionalOnProperty(name = "usemongodb", havingValue = "local")
DataSource
dataSource()
{
// Insert code here
}

@Bean
@ConditionalOnProperty(name = "usemongodb",
havingValue = "prod")

DataSource
dataSource()
{
// Insert code here
}

8. @ConditionalOnResource Annotation
These annotations are used to let configuration be included only when a
specific resource is present in the classpath.
@ConditionalOnResource(resources = "classpath:mongodb.properties")

Properties
additionalProperties()
{
// Insert code here
}

9. @ConditionalOnExpression Annotation
These annotations are used to let configuration be included based on the
result of a SpEL (Spring Expression Language) expression.
@Bean
@ConditionalOnExpression("${env} && ${havingValue == 'local'}")

DataSource dataSource()
{
// Insert code here
}
10. @ConditionalOnCloudPlatform Annotation
These annotations are used to let configuration be included when the
specified cloud platform is active.
@Configuration
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)

public class CloudConfigurationExample


{
// Insert code here
}
Spring – Auto wiring
The Spring framework can inject dependencies automatically. The Spring
container detects those dependencies specified in the configuration file and
@ the relationship between the beans. This is referred to as autowiring in
Spring. An autowired application requires fewer lines of code comparatively
but at the same time, it provides very little flexibility to the programmer.

There are five modes of autowiring:


It is not required to specify all the properties values while defining bean in the configuration. For
non-primitive properties we can use the Autowiring feature.

If Autowiring is enabled, Spring container automatically initializes the dependencies of that bean.

There is no need to provide explicit <property > or <constructor-arg> with ref tags in the bean
definition for object dependencies.

Autowiring cannot be used to inject primitive and string values.


Spring automatically inject the bean dependency. The autowiring has four modes.

 no (no autowiring)
 byName
 byType
 constructor
 autodetect

In XML configuration, autowire mode is specified in the bean definition using


the autowire attribute.

Mode Description
 Bean dependency is autowired based on the property name
 If the matching bean does not exist in the container then bean
byName will remain unwired
 It internally uses setter injection

 Autowiring the bean dependency based on the property type


 Properties for which there is no matching bean will remain
unwired.
byType  Spring throws an exception if there is more than one bean of
the same type exists in the container
 It internally uses setter injection

constructo  It is the same as autowiring byType but through constructor


r arguments.
Mode Description

 Spring autowire the dependency based on constructor


argument type through constructor injection.
 Spring throws an exception if there is more than one bean of
same type exists in the container

no Default mode which means no autowiring

byName
It uses the name of the bean for injecting dependencies. However, it
requires that the name of the property and bean must be the same.
(City in the above class) Mention an
attribute autowire value "byName". It invokes the setter method internally for
autowiring.

<bean id="state" class="sample.State">


<property name="name" value="UP" />
</bean>
<bean id="city" class="sample.City" autowire="byName"></bean>

byType
It injects the dependency according to the type of the bean. It looks up in the
configuration file for the class type of the property. If it finds a bean that
matches, it injects the property. If not, the program throws an error. The
names of the property and bean can be different in this case. It invokes the
setter method internally for autowiring.
<bean id="state" class="sample.State">
<property name="name" value="UP" />
</bean>
<bean id="city" class="sample.City" autowire="byType"></bean>
constructor
It injects the required dependencies by invoking the constructor. It works
similar to the “byType” mode but it looks for the class type of the constructor
arguments. If none or more than one bean are detected, then it throws an
error, otherwise, it autowires the “byType” on all constructor arguments.

<bean id="state" class="sample.State">

<property name="name" value="UP" />


</bean>

<bean id="city" class="sample.City" autowire="constructor"></bean>

No
This mode tells the framework that autowiring is not supposed to be done. It
is the default mode used by Spring.
<bean id="state" class="sample.State">
<property name="name" value="UP" />
</bean>
<bean id="city" class="sample.City"></bean>

Bean Scopes

Bean Scopes refers to the lifecycle of Bean.


When object of Bean instantiated:
 how long does that object live
 how many objects will be created for that bean
 it controls the instance creation of the bean
 it is managed by the spring container.

The following are the different scopes provided for a bean:


1. Singleton: Only one instance will be created for a single bean definition
per Spring IoC container. The same object will be shared for each request
made for that bean.
2. Prototype: A new instance will be created for a single bean definition
every time a request is made for that bean.
3. Request: A new instance will be created for a single bean definition every
time an HTTP request is made for that bean. But Only valid in the
context of a web-aware Spring ApplicationContext.
4. Session: Scopes a single bean definition to the lifecycle of an HTTP
Session. But Only valid in the context of a web-aware Spring
ApplicationContext.
5. Global-Session: Scopes a single bean definition to the lifecycle of a
global HTTP Session. It is also only valid in the context of a web-aware
Spring ApplicationContext.

Singleton Scope:

If the scope is a singleton:


only one instance of that bean will be icreated per Spring IoC
container. The same instance will be shared for each request.
That is when the scope of a bean is declared singleton, then whenever a
new request is made for that bean , spring IOC container first checks
whether an instance of that bean is already created or not. If it is already
created, then the IOC container returns the same instance otherwise it
creates a new instance of that bean only at the first request. By
default, the scope of a bean is a singleton.

// Java program to illustrate a bean created in the spring framework

package bean;

public class HelloWorld {


public String name;

// Create a setter method to set the value passed by user


public void setName(String name)
{
this.name = name;
}

// Create a getter method so that the user can get the set value
public String getName()
{
return name;
}
}

<!DOCTYPE beans PUBLIC


"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!--configure the bean HelloWorld.java
and declare its scope-->
< bean
id = "hw"
class= "bean.HelloWorld"
scope = "singleton" / >
</beans>

// Java program to illustrate


// the client to perform the
// request to the defined bean

package driver;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import bean.HelloWorld;

// Client Class to request the


// above defined bean
public class Client {

public static void main(String[] args)


{
// Load the Spring XML configuration
IoC container
// file into

ApplicationContext ap = new ClassPathXmlApplicationContext(


"resources/spring.xml");

// Get the "HelloWorld" bean object


// and call getName() method
HelloWorld Geeks1 = (HelloWorld) ap.getBean(" hw");
// Set the name
Geeks1.setName("Geeks1");
System.out.println( "Hello object (hello1)" + " Your name is: " + Geeks1.getName());

// Get another "HelloWorld" bean object


// and call getName() method

HelloWorld Geeks2 = (HelloWorld)ap.getBean(" hw");


System.out.println( "Hello object (hello2)"+ " Your name is: "+ Geeks2.getName());

// Now compare the references to see // whether they are pointing to the
// same object or different object

System.out.println(
"'Geeks1' and 'Geeks2'" + " are referring" + "to the same object: "
+( Geeks1 == Geeks2));
}
}

Output :

Hello object (hello1) Your name is: Geeks1


Hello object (hello2) Your name is: Geeks1
'Geeks1' and 'Geeks2' are referring to the same object: true

When we call the getName() method by using the reference of ‘Geeks1’ and
‘Geeks2’, then we are getting the same outputs. This means that both the
reference is calling the getName() method of the same object. Furthermore,
when we are comparing the reference ‘Geeks1’ and ‘Geeks2’ then output is
“true” which means the same object is shared between ‘Geeks1’ and
‘Geeks2’.

Prototype Scope:

a
If the scope is declared prototype, then spring IOC container will create
new instance of that bean every time a request is made
for that specific bean. A request can be made to the bean instance
either programmatically using getBean() method or by XML for Dependency
Injection of secondary type. Generally, we use the prototype scope for all
beans that are stateful, while the singleton scope is used for the stateless
beans.

// Java program to illustrate a bean


// created in the spring framework
package bean;

public class HelloWorld {


public String name;

// Create a setter method to


// set the value passed by user
public void setName(String name)
{
this.name = name;
}

// Create a getter method so that


// the user can get the set value
public String getName()
{
return name;
}
}

<!DOCTYPE beans PUBLIC


"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
< beans>
<!--configure the bean HelloWorld.java
and declare its scope-->
< bean
id = "hw"
class = "bean.HelloWorld"
scope = "prototype" / >
</ beans>

// Java program to illustrate


// the client to perform the
// request to the defined bean

package driver;

import org.springframework
.context.ApplicationContext;

import org.springframework.context.support
.ClassPathXmlApplicationContext;

import bean.HelloWorld;

public class Client {

public static void main(String[] args)


{
// Load the Spring XML configuration
// file into IoC container
ApplicationContext ap
= new ClassPathXmlApplicationContext(
"resources/spring.xml");

// Get the "HelloWorld" bean object


// and call getName() method

HelloWorld Geeks1 = (HelloWorld)ap.getBean(" hw");


// Set the name
Geeks1.setName("Geeks1");
System.out.println(
"Hello object (hello1)" + " Your name is: "+ Geeks1.getName());

// Get another "HelloWorld" bean object


// and call getName() method
HelloWorld Geeks2
= (HelloWorld)ap.getBean("hw");
// FOR GREEK2 we did not set the value
System.out.println(
"Hello object (hello2)" + "Your name is: "+ Geeks2.getName());

// Now compare the references to see


// whether they are pointing to the
// same object or different object
System.out.println(
"'Geeks1' and 'Geeks2'" + "are referring " + "to the same object: "
+ (Geeks1 == Geeks2));

}
}

Hello object (hello1) Your name is: Geeks1


Hello object (hello2) Your name is: null
'Geeks1' and 'Geeks2' are referring to the same object:
false

When we call getName() method by using the reference ‘Geeks1’ and


‘Geeks2’, then we get different outputs that means both the reference is
calling getName() method of a different object. Furthermore, when we are
comparing the reference ‘Geeks1’ and ‘Geeks2’ then output is “false” which
means both references is referring to a different object. So it is clear that a
new instance of bean (HelloWorld) is being created at each request made for
this bean.

 Difference between Singleton and Prototype

Singleton Prototype

A new instance is created for a single


Only one instance is created for a single
bean definition every time a request is
bean definition per Spring IoC container
made for that bean.

Same object is shared for each request For each new request a new instance is
made for that bean. i.e. The same object is created. i.e. A new object is created
returned each time it is injected. each time it is injected.

By default scope of a bean is singleton. So By default scope is not prototype so you


we don’t need to declare a been as have to declare the scope of a been as
Singleton Prototype

singleton explicitly. prototype explicitly.

Singleton scope should be used for While prototype scope is used for all
stateless beans. beans that are stateful

Request, Session, Application, and WebSocket Scopes:


The request, session, application, and websocket scopes are available only
if you use a web-aware Spring ApplicationContext implementation (such as
XmlWebApplicationContext).
If you use these scopes with regular Spring IoC containers, such as the
ClassPathXmlApplicationContext, an IllegalStateException that
complains about an unknown bean scope is thrown.

Initial Web Configuration


To support the scoping of beans at the request, session, application, and
websocket levels (web-scoped beans), some minor initial configuration is
required before you define your beans.

<web-app>
...
<listener>
<listener-class>

org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>

Request scope
Consider the following XML configuration for a bean definition:

<bean id="loginAction" class="com.something.LoginAction" scope="request"/>

The Spring container creates a new instance of the LoginAction


bean by using the loginAction bean definition for each and every HTTP
request.
That is, the loginAction bean is scoped at the HTTP request level.
You can change the internal state of the instance that is created as
much as you want, because other instances created from the same
loginAction bean definition do not see these changes in state. They are
the request completes
particular to an individual request. When
processing, the bean that is scoped to the request is
discarded.
When using annotation-driven components or Java configuration, the
@RequestScope annotation can be used to assign a component to the
request scope. The following example shows how to do so:

When using annotation-driven components or Java configuration, the


@RequestScope annotation can be used to assign a component to the
request scope. The following example shows how to do so:

Session Scope
Consider the following XML configuration for a bean definition:

<bean id="userPreferences" class="com.something.UserPreferences"


scope="session"/>

The Spring container creates a new instance of the UserPreferences bean


for the lifetime of a single HTTP Session. That is, the userPreferences bean
is scoped is the HTTP Session level.
As with request-scoped beans, you can change the internal state of the
instance that is created as much as you want, knowing that other HTTP
Session instances that are also using instances created from the same
userPreferences bean definition do not see these changes in state, because
they are particular to an individual HTTP Session. When the HTTP Session
is eventually discarded, the bean that is scoped to that particular HTTP
Session is also discarded.

When using annotation-driven components or Java configuration, you can use the @SessionScope
annotation to assign a component to the session scope.

@SessionScope
@Component
public class UserPreferences {
// ...
}

Application Scope
Consider the following XML configuration for a bean definition:

<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>

The Spring container creates a new instance of the AppPreferences bean by using the
appPreferences bean definition once for the entire web application. That is, the appPreferences
bean is scoped at the ServletContext level and stored as a regular ServletContext attribute. This is
somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per
ServletContext, not per Spring ApplicationContext (for which there may be several in any given web
application), and it is actually exposed and therefore visible as a ServletContext attribute.

When using annotation-driven components or Java configuration, you can use the
@ApplicationScope annotation to assign a component to the application scope. The following
example shows how to do so:
@ApplicationScope
@Component
public class AppPreferences {
// ...
}

Logging
A good logging infrastructure is necessary for any software project. It helps
in understanding what’s going on with the application. It also to trace any
unusual incident or error present in the project.
Spring Boot’s default configurations provides a support for the use of Java Util Logging,
Log4j2, and Logback. Using these, we can configure the console logging as well as file
logging.
The default Spring Boot Log format gives you the following information:
 Date and Time that gives the date and time of the log
 Log level shows INFO, ERROR or WARN
 Process ID
 The --- which is a separator
 Thread name is enclosed within the square brackets []
 Logger Name that shows the Source class name
Console Log Output
The default log messages will print to the console window. By default, “INFO”,
“ERROR” and “WARN” log messages will print in the log file.
If you have to enable the debug level log, add the debug flag on starting your
application using the command shown below
java –jar demo.jar –debug
You can also add the debug mode to your application.properties file as shown here −
debug = true

File Log Output


By default, all logs will print on the console window and not in the files. If you want to
print the logs in a file, you need to set the property logging.file or logging.path in
the application.properties file.
You can specify the log file path using the property shown below. Note that the log
file name is spring.log.
logging.path = /var/tmp/
You can specify the own log file name using the property shown below −
logging.file = /var/tmp/mylog.log

Note − files will rotate automatically after reaching the size 10 MB.

Log Levels
Spring Boot supports all logger levels such as “TRACE”, “DEBUG”, “INFO”, “WARN”,
“ERROR”, “FATAL”, “OFF”. You can define Root logger in the application.properties
file as shown below −
logging.level.root = WARN
Note − Logback does not support “FATAL” level log. It is mapped to the “ERROR”
level log.
Configure Logback
Logback supports XML based configuration to handle Spring Boot Log
configurations. Logging configuration details are configured in logback.xml file. The
logback.xml file should be placed under the classpath.
You can configure the ROOT level log in Logback.xml file using the code given
below
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<root level = "INFO">
</root>
</configuration>

You can configure the console appender in Logback.xml file given below.
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<appender name = "STDOUT" class =
"ch.qos.logback.core.ConsoleAppender"></appender>
<root level = "INFO">
<appender-ref ref = "STDOUT"/>
</root>
</configuration>

The code for complete logback.xml file is given below. You have to place this in the
class path.
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<appender name = "STDOUT" class =
"ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p]
%m%n</pattern>
</encoder>
</appender>

<appender name = "FILE" class = "ch.qos.logback.core.FileAppender">


<File>/var/tmp/mylog.log</File>
<encoder>
<pattern>[%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p]
%m%n</pattern>
</encoder>
</appender>

<root level = "INFO">


<appender-ref ref = "FILE"/>
<appender-ref ref = "STDOUT"/>
</root>
</configuration>

The code given below shows how to add the slf4j logger in Spring Boot
main class file.

// Rest Controller to print various log level messages


package com.log.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogController {

// creating a logger
Logger logger
= LoggerFactory.getLogger(LogController.class);

@RequestMapping("/log") public String log()


{
// Logging various log level messages
logger.trace("Log level: TRACE");
logger.info("Log level: INFO");
logger.debug("Log level: DEBUG");
logger.error("Log level: ERROR");
logger.warn("Log level: WARN");

return "Hey! You can check the output in the logs";


}
}

Aspect Oriented Programming and AOP in Spring Framework

It can be defined as the breaking of code into different


modules, also known as modularisation, where the aspect is the key unit
of modularity.
For example- Security is a crosscutting concern. Instead of repeating the
code at every method, define the functionality in a common class and control
were to apply that functionality in the whole application.

Spring AOP module provides interceptors to intercept an application. For example, when a
method is executed, you can add extra functionality before or after the method execution.

Dominant Frameworks in AOP:


AOP includes programming methods and frameworks on which
modularisation of code is supported and implemented. Let’s have a
look at the three dominant frameworks in AOP:


Spring: It uses XML based configuration for implementing AOP,
also it uses annotations which are interpreted by using a library
supplied by AspectJ for parsing and matching.

AOP breaks the program logic into distinct parts. Each part is called a
concern. It is used to increase modularity by cross-cutting
concerns.

A cross-cutting concern is a concern that can affect the whole application and
should be centralized in one location in code as possible,
such as transaction management, authentication, logging, security etc.
Why use AOP?

It provides the pluggable way to dynamically add the additional concern


before, after or around the actual logic.

class A{
public void m1(){...}
public void m2(){...}
public void m3(){...}
public void m4(){...}
public void m5(){...}
public void n1(){...}
public void n2(){...}
public void p1(){...}
public void p2(){...}
public void p3(){...}
}

There are 5 methods that starts from m, 2 methods that starts from n and
3 methods that starts from p.

Understanding Scenario I have to maintain log and send


notification after calling methods that starts from m.
Problem without AOP We can call methods (that maintains
log and sends notification) from the methods starting with m. In
such scenario, we need to write the code in all the 5 methods.

But, if client says in future , I don't have to send notification,


you need to change all the methods. It leads to the maintenance problem.

Solution with AOP We don't have to call methods from


the method. Now we can define the additional concern like
maintaining log, sending notification etc. in the method of a class. Its
entry is given in the xml file.
In future, if client says to remove the notifier functionality, we need to
change only in the xml file. So, maintenance is easy in AOP.
AOP Concepts and Terminology
AOP concepts and terminologies are as follows:

o Join point
o Advice
o Pointcut
o Introduction
o Target Object
o Aspect
o Interceptor
o AOP Proxy
o Weaving

Join point
any point in your program such as
Join point is
method execution, exception handling, field
access etc. But Spring AOP currently supports only method execution
join points
Aspect
This is a module which has a set of APIs providing requirements. For example, a
logging module would be called AOP aspect for logging. An application can have any
number of aspects depending on the requirement.
For Example, we can have security AOP, transaction AOP, notification AOP.
Spring supports the @AspectJ annotation style approach and the schema-
based approach to implement custom aspects.
XML Schema based
Aspects are implemented using the regular classes along with XML based
configuration.
@AspectJ based
@AspectJ refers to a style of declaring aspects as regular Java classes annotated
with Java 5 annotations.

Advice

an action taken by an aspect at a


Advice represents
particular join point. There are different types of advices:
o Before Advice: it executes before a join point. It is denoted
by @Before annotation.
o After Returning Advice: it executes after a joint point completes
normally It is denoted by @AfterReturning annotation.
o After Throwing Advice: it executes if method exits by throwing an
exception. It is denoted by @AfterThrowing annotation.
o After (finally) Advice: it executes after a join point regardless of join
point exit whether normally or exceptional return. . It is denoted
by @After annotation.
o Around Advice: It executes before and after a join
point. It is denoted by @Around annotation.

Pointcut
This is a set of one or more join points where an advice should be executed. You
can specify pointcuts using expressions or patterns as we will see in our AOP
examples.
Introduction
An introduction allows you to add new methods or attributes to the existing classes.
Target object
The object being advised by one or more aspects. This object will always be a
proxied object, also referred to as the advised object.

Weaving
Weaving is the process of linking aspects with other application types or objects to
create an advised object. This can be done at compile time, load time, or at runtime.

Spring Boot Best Practices


1. Using Auto-configuration
Spring Boot auto-configuration attempts to automatically configure your
Spring application based on the jar dependencies that you have added.
The simplest way to make use of it is to rely on the Spring Boot Starters.
So, if you want to interact with Redis, you can start by including:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

if you want to work with MongoDB, you have:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

By relying on these starters, you are relying on a tested and proven


configuration that is going to work well together.
It is possible to exclude some classes from the Auto-configuration, by
using the following annotation
property: @EnableAutoConfiguration(exclude={ClassNotToAutoconfigure.
class}), but you should do it only if absolutely necessary.
2. When to Use Constructor-based and setter-
based DI in Spring or Spring boot
applications

As we know that there are three possible ways of DI in Spring:

1. Constructor-based dependency injection


2. Setter-based dependency injection
3. Field-based dependency injection

From spring Framework documentation, since you can


mix constructor-based and setter-based DI, it is a good rule of thumb
to use constructors for mandatory dependencies and setter methods or
configuration methods for optional dependencies.

As I can see many developers prefer to use constructor injection over


setter based injection because this makes bean class object as
immutable(We cannot change the value by Constructor injection).

For example, define dependencies as final variables like:

@Service
@Transactional
public class ProductService {
private final ProductRepository productRepository;

public ProductService(ProductRepository productRepository) {


this.productRepository= productRepository;
}
}

This way it will be easier to instantiate ProductService with necessary


dependencies for testing if required.

4. Using @Service Annotation


Class for Business Layer
I observed in many of the spring boot open-source applications, the
Spring Data JPA repositories directly called in Controller classes in
Spring boot applications. I generally use Service class annotated
with a @Service annotation to write business-related logic so you
can follow this approach.

For example, UserService, CustomerService, EmployeeService etc.


5. Spring Bean Naming
Conventions
The convention is to use the standard Java convention for instance
field names when naming beans. That is, bean names start with a
lowercase letter, and are camel-cased from then on.
Examples of such names would be (without quotes)
'accountManager', 'accountService', 'userDao',
'loginController', and so forth.
Naming beans consistently make your configuration easier to read
and understand, and if you are using Spring AOP it helps a lot when
applying advice to a set of beans related by name.

Spring Bean Naming Conventions in Java-based config

Spring Bean Naming Conventions in an annotation-based


config
6. Handle Circular dependencies

If you use predominantly constructor injection, it is possible to


create an unresolvable circular dependency scenario.

For example - Class A requires an instance of class B through


constructor injection, and class B requires an instance of
class A through constructor injection. If you configure beans for
classes A and B to be injected into each other, the Spring IoC
container detects this circular reference at runtime and throws
a BeanCurrentlyInCreationException.

public class A {
public A(B b){
....
}
}
public class B {
public B(A b){
....
}
}
One possible solution is to edit the source code of some classes to be configured
by setters rather than constructors. Alternatively, avoid constructor injection and
use setter injection only. In other words, although it is not recommended, you
can configure circular dependencies with setter injection.

7. exception Handling in
Spring boot Rest API projects
Handle proper exceptions and custom error messages for RESTful Web Services
developed using Spring Boot.

8. Follow Restful API Design Best Practices in Spring


Boot Rest API Applications

Here is a list of best practices to design a clean RESTful API.


9. use Spring Initializer for
starting new Spring Boot
projects
There are many ways to create a Spring Boot application. The simplest
way is to use Spring Initializr at http://start.spring.io/, which is an online
Spring Boot application generator.

10. Using Java-based


configuration -
@Configuration
Spring Boot favors Java-based configuration. Although it is possible to
use SpringApplication with XML sources, I generally recommend that your
primary source be a single @Configuration class. Usually, the class that defines
the main method is a good candidate as the primary @Configuration or
@SpringBootApplication annotation.

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

It is always a good practice to divide a large Spring-based configuration file into


multiple files as per your convenience. I generally keep Database configuration
in one file (DatabaseConfig), Spring MVC beans in another file, etc, and then
finally import in the main file.

Importing Additional Configuration Classes

You need not put all your @Configuration into a single class. The @Import
annotation can be used to import additional configuration classes.
For example:

@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new DriverManagerDataSource(...);
}
}

Multiple configurations may be imported by supplying an array of classes to


the @Import annotation:

@Configuration
@Import({ DataSourceConfig.class, TransactionConfig.class })
public class AppConfig extends ConfigurationSupport {
// @Bean methods here can reference @Bean methods in DataSourceConfig
or TransactionConfig
}

You might also like