Unit 2
Unit 2
Spring Boot
Spring Boot :
Spring Boot provides basic and advanced concepts of Spring Framework. Spring Boot is a
Spring module that provides the RAD (Rapid Application Development) feature to the Spring
framework. Spring Boot makes it easy to create stand-alone, production-grade Spring based
Applications that you can "just run". Most Spring Boot applications need minimal Spring
configuration. Spring Boot gives an easier, quicker path to set up, configure, and run apps. It
eliminates the heavy lifting of configuration that is required for setting up most Spring-based
apps. Developers can jump right in and use Spring Boot without ever having to learn the
underlying Spring framework.
Spring Boot is a project that is built on the top of the Spring Framework. It provides an easier
and faster way to set up, configure, and run both simple and web-based applications.
It is a Spring module that provides the RAD (Rapid Application Development) feature to the
Spring Framework. It is used to create a stand-alone Spring-based application that you can
just run because it needs minimal Spring configuration.
In short, Spring Boot is the combination of Spring Framework and Embedded Servers.
We can use Spring STS IDE or Spring Initializer to develop Spring Boot Java applications.
o Spring Data: It simplifies data access from the relational and NoSQL databases.
o Spring Batch: It provides powerful batch processing.
o Spring Security: It is a security framework that provides robust security to applications.
o Spring Social: It supports integration with social networking like LinkedIn.
o Spring Integration: It is an implementation of Enterprise Integration Patterns. It facilitates
integration with other enterprise applications using lightweight messaging and declarative
adapters.
Spring Boot can use dependencies that are not going to be used in the application. These
dependencies increase the size of the application.
The main goal of Spring Boot is to reduce development, unit test, and integration test time.
To create a Spring Boot application, following are the prerequisites. In this tutorial, we will
use Spring Tool Suite (STS) IDE.
o Java 1.8
o Maven 3.0+
o Spring Framework 5.0.0.BUILD-SNAPSHOT
o An IDE (Spring Tool Suite) is recommended.
Web Development
It is a well-suited Spring module for web application development. We can easily create a
self-contained HTTP application that uses embedded servers like Tomcat, Jetty, or
Undertow. We can use the spring-boot-starter-web module to start and run the application
quickly.
Spring Application
Spring Boot uses events to handle the variety of tasks. It allows us to create factories file that
is used to add listeners. We can refer it to using the ApplicationListener key.
Admin Support
Spring Boot provides the facility to enable admin-related features for the application. It is
used to access and manage applications remotely. We can enable it in the Spring Boot
application by using spring.application.admin.enabled property.
Externalized Configuration
Spring Boot allows us to externalize our configuration so that we can work with the same
application in different environments. The application uses YAML files to externalize
configuration.
Properties Files
Spring Boot provides a rich set of Application Properties. So, we can use that in the
properties file of our project. The properties file is used to set properties like server-port
=8082 and many others. It helps to organize application properties.
YAML Support
Type-safe Configuration
The strong type-safe configuration is provided to govern and validate the configuration of the
application. Application configuration is always a crucial task which should be type-safe. We
can also use annotation provided by this library.
Logging
Spring Boot uses Common logging for all internal logging. Logging dependencies are
managed by default. We should not change logging dependencies if no customization is
needed.
Security
Spring Boot applications are spring bases web applications. So, it is secure by default with
basic authentication on all HTTP endpoints. A rich set of Endpoints is available to develop a
secure Spring Boot application.
Step 2: Provide the Group and Artifact name. We have provided Group
name com.javatpoint and Artifact spring-boot-example.
When we click on the Generate button, it starts packing the project in a .rar file and
downloads the project.
File -> Import -> Existing Maven Project -> Next -> Browse -> Select the project -> Finish
It takes some time to import the project. When the project imports successfully, we can see
the project directory in the Package Explorer. The following image shows the project
directory:
SpringBootExampleApplication.java
1. package com.javatpoint.springbootexample;
2. import org.springframework.boot.SpringApplication;
3. import org.springframework.boot.autoconfigure.SpringBootApplication;
4. @SpringBootApplication
5. public class SpringBootExampleApplication
6. {
7. public static void main(String[] args)
8. {
9. SpringApplication.run(SpringBootExampleApplication.class, args);
10. }
11. }
pom.xml
The springbootapplication annotation helps the developers to mark configuration classes. The
main three features of a springbootapplication annotation are as follows:
@EnablAutoConfiguration: Because of this feature, the application automatically produces
and registers bean methods depending on both the jar files on the included classpath and the
beans we define.
Example:
@Configuration
@EnableAutoConfiguration
//Application Class or Main Class
public class Main {
//Main method
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
@Configuration: It tries to configure your Spring application automatically based on the jar
dependencies you provided. You can use properties files, YAML files, environment
variables, and command-line arguments to externalise configuration.
Example:
@Configuration
//Main method
@bean
// bean method's name or id
public CN cnBean() { // Returning the CN object
//Main method
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
// works same as @EnableAutoConfiguration, @Configuration, and @ComponentScan.
The above code simply calls the SpringApplication.run() method. This launches the
embedded beans and launches the Spring application as separate applications. One can place
this code in the root package. It will help in component scanning and searching for beans in
every sub-package.
Optional Parameters:
The @SpringBootApplication annotation accepts the following parameters:
Class<?>[] exclude: Make certain auto-configuration classes irrelevant by
excluding them.
Optional Features:
The @SpringBootApplication annotation offers aliases to modify the
@EnableAutoConfiguration @Configuration and @ComponentScan's attributes. We can
replace the springbootapplication annotation with any of these annotations, but none of these
features is required. For example, you can use the springbootapplication annotation without
the @ComponentScan method.
Here is the code for implementing the springbootapplication annotation without the
@ComponentScan method.
package example;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
@Configuration
@EnableAutoConfiguration
//Not using the @ComponentScan
Autowiring in Spring
Autowiring feature of spring framework enables you to inject the object dependency
implicitly. It internally uses setter or constructor injection.
Autowiring can't be used to inject primitive and string values. It works with reference only.
Advantage of Autowiring
It requires less code because we don't need to write the code to inject the dependency
explicitly.
Disadvantage of Autowiring
No control of programmer.
Autowiring Modes
No Mode Description
.
2) byName The byName mode injects the object dependency according to name of the
bean. In such case, property name and bean name must be same. It internally
calls setter method.
3) byType The byType mode injects the object dependency according to type. So property
name and bean name can be different. It internally calls setter method.
4) Constructor The constructor mode injects the dependency by calling the constructor of the
class. It calls the constructor having large number of parameters.
Let's see the simple code to use autowiring in spring. You need to use autowire attribute of
bean element to apply the autowire modes.
Let's see the full example of autowiring in spring. To create this example, we have created 4
files.
1. B.java
2. A.java
3. applicationContext.xml
4. Test.java
B.java
1. package org.sssit;
2. public class B {
3. B(){System.out.println("b is created");}
4. void print(){System.out.println("hello b");}
5. }
A.java
1. package org.sssit;
2. public class A {
3. B b;
4. A(){System.out.println("a is created");}
5. public B getB() {
6. return b;
7. }
8. public void setB(B b) {
9. this.b = b;
10. }
11. void print(){System.out.println("hello a");}
12. void display(){
13. print();
14. b.print();
15. }
16. }
applicationContext.xml
Test.java
This class gets the bean from the applicationContext.xml file and calls the display method.
1. package org.sssit;
2. import org.springframework.context.ApplicationContext;
3. import org.springframework.context.support.ClassPathXmlApplicationContext;
4. public class Test {
5. public static void main(String[] args) {
6. ApplicationContext context=new ClassPathXmlApplicationContext("applicationCo
ntext.xml");
7. A a=context.getBean("a",A.class);
8. a.display();
9. }
10. }
Output:
b is created
a is created
hello a
hello b
1) byName autowiring mode
In case of byName autowiring mode, bean id and reference name must be same.
But, if you change the name of bean, it will not inject the dependency.
Let's see the code where we are changing the name of the bean from b to b1.
In case of byType autowiring mode, bean id and reference name may be different. But there
must be only one bean of a type.
In this case, it works fine because you have created an instance of B type. It doesn't matter
that you have different bean name than reference name.
But, if you have multiple bean of one type, it will not work and throw exception.
In case of constructor autowiring mode, spring container injects the dependency by highest
parameterized constructor.
If you have 3 constructors in a class, zero-arg, one-arg and two-arg then injection will be
performed by calling the two-arg constructor.
4) no autowiring mode
In case of no autowiring mode, spring container doesn't inject the dependency by autowiring.
The scope of a bean defines the life cycle and visibility of that bean in the contexts we use it.
The latest version of the Spring framework defines 6 types of scopes:
singleton
prototype
request
session
application
websocket
The last four scopes mentioned, request, session, application and websocket, are only
available in a web-aware application.
1. Singleton Scope
When we define a bean with the singleton scope, the container creates a single instance of
that bean; all requests for that bean name will return the same object, which is cached. Any
modifications to the object will be reflected in all references to the bean. This scope is the
default value if no other scope is specified.
Let’s create a Person entity to exemplify the concept of scopes:
public class Person {
private String name;
We can also use a constant instead of the String value in the following manner:
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)Copy
Now we can proceed to write a test that shows that two objects referring to the same bean
will have the same values, even if only one of them changes their state, as they are both
referencing the same bean instance:
private static final String NAME = "John Smith";
@Test
public void givenSingletonScope_whenSetName_thenEqualNames() {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("scopes.xml");
personSingletonA.setName(NAME);
Assert.assertEquals(NAME, personSingletonB.getName());
((AbstractApplicationContext) applicationContext).close();
}
The scopes.xml file in this example should contain the xml definitions of the beans used:
<?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.xsd">
2. Prototype Scope
A bean with the prototype scope will return a different instance every time it is requested
from the container. It is defined by setting the value prototype to the @Scope annotation in
the bean definition:
@Bean
@Scope("prototype")
public Person personPrototype() {
return new Person();
}
We can also use a constant like we did for the singleton scope:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)Copy
We will now write a similar test as before that shows two objects requesting the same bean
name with the prototype scope. They will have different states as they are no longer referring
to the same bean instance:
private static final String NAME = "John Smith";
private static final String NAME_OTHER = "Anna Jones";
@Test
public void givenPrototypeScope_whenSetNames_thenDifferentNames() {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("scopes.xml");
personPrototypeA.setName(NAME);
personPrototypeB.setName(NAME_OTHER);
Assert.assertEquals(NAME, personPrototypeA.getName());
Assert.assertEquals(NAME_OTHER, personPrototypeB.getName());
((AbstractApplicationContext) applicationContext).close();
}
The scopes.xml file is similar to the one presented in the previous section while adding the
xml definition for the bean with the prototype scope:
<bean id="personPrototype" class="org.baeldung.scopes.Person" scope="prototype"/>Copy
As previously mentioned, there are four additional scopes that are only available in a web-
aware application context. We use these less often in practice.
The request scope creates a bean instance for a single HTTP request, while the session scope
creates a bean instance for an HTTP Session.
The application scope creates the bean instance for the lifecycle of a ServletContext, and
the websocket scope creates it for a particular WebSocket session.
Let’s create a class to use for instantiating the beans:
public class HelloMessageGenerator {
private String message;
We can define the bean with the request scope using the @Scope annotation:
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode =
ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator requestScopedBean() {
return new HelloMessageGenerator();
}
The proxyMode attribute is necessary because at the moment of the instantiation of the web
application context, there is no active request. Spring creates a proxy to be injected as a
dependency, and instantiates the target bean when it is needed in a request.
We can also use a @RequestScope composed annotation that acts as a shortcut for the above
definition:
@Bean
@RequestScope
public HelloMessageGenerator requestScopedBean() {
return new HelloMessageGenerator();
}
Next we can define a controller that has an injected reference to the requestScopedBean. We
need to access the same request twice in order to test the web specific scopes.
If we display the message each time the request is run, we can see that the value is reset
to null, even though it is later changed in the method. This is because of a different bean
instance being returned for each request.
@Controller
public class ScopesController {
@Resource(name = "requestScopedBean")
HelloMessageGenerator requestScopedBean;
@RequestMapping("/scopes/request")
public String getRequestScopeMessage(final Model model) {
model.addAttribute("previousMessage", requestScopedBean.getMessage());
requestScopedBean.setMessage("Good morning!");
model.addAttribute("currentMessage", requestScopedBean.getMessage());
return "scopesExample";
}
}
We can define the bean with the session scope in a similar manner:
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode =
ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator sessionScopedBean() {
return new HelloMessageGenerator();
}
There’s also a dedicated composed annotation we can use to simplify the bean definition:
@Bean
@SessionScope
public HelloMessageGenerator sessionScopedBean() {
return new HelloMessageGenerator();
}
Next we define a controller with a reference to the sessionScopedBean. Again, we need to run
two requests in order to show that the value of the message field is the same for the session.
In this case, when the request is made for the first time, the value message is null. However,
once it is changed, that value is retained for subsequent requests as the same instance of the
bean is returned for the entire session.
@Controller
public class ScopesController {
@Resource(name = "sessionScopedBean")
HelloMessageGenerator sessionScopedBean;
@RequestMapping("/scopes/session")
public String getSessionScopeMessage(final Model model) {
model.addAttribute("previousMessage", sessionScopedBean.getMessage());
sessionScopedBean.setMessage("Good afternoon!");
model.addAttribute("currentMessage", sessionScopedBean.getMessage());
return "scopesExample";
}
}
The application scope creates the bean instance for the lifecycle of a ServletContext.
This is similar to the singleton scope, but there is a very important difference with regards to
the scope of the bean.
When beans are application scoped, the same instance of the bean is shared across multiple
servlet-based applications running in the same ServletContext, while singleton scoped beans
are scoped to a single application context only.
Let’s create the bean with the application scope:
@Bean
@Scope(
value = WebApplicationContext.SCOPE_APPLICATION, proxyMode =
ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator applicationScopedBean() {
return new HelloMessageGenerator();
}
Analogous to the request and session scopes, we can use a shorter version:
@Bean
@ApplicationScope
public HelloMessageGenerator applicationScopedBean() {
return new HelloMessageGenerator();
}
@RequestMapping("/scopes/application")
public String getApplicationScopeMessage(final Model model) {
model.addAttribute("previousMessage", applicationScopedBean.getMessage());
applicationScopedBean.setMessage("Good afternoon!");
model.addAttribute("currentMessage", applicationScopedBean.getMessage());
return "scopesExample";
}
}
In this case, once set in the applicationScopedBean, the value message will be retained for all
subsequent requests, sessions and even for different servlet applications that will access this
bean, provided it is running in the same ServletContext.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
Business Object
A business object is a normal class that has a normal business logic. Let’s look at a simple
example of a business object where we just add two numbers:
public class SampleAdder {
public int add(int a, int b) {
return a + b;
}
}
Note that this class is a normal class with business logic, without any Spring-related
annotations.
Aspect
An aspect is a modularization of a concern that cuts across multiple classes. Unified logging
can be an example of such cross-cutting concern.
Let’s see how we define a simple Aspect:
public class AdderAfterReturnAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void afterReturn(Object returnValue) throws Throwable {
logger.info("value return was {}", returnValue);
}
}
In the above example, we defined a simple Java class that has a method
called afterReturn, which takes one argument of type Object and logs in that value. Note that
even our AdderAfterReturnAspect is a standard class, free of any Spring annotations.
In the next sections, we’ll see how we can wire this Aspect to our Business Object.
Joinpoint
A Joinpoint is a point during the execution of a program, such as the execution of a method
or the handling of an exception.
In Spring AOP, a JoinPoint always represents a method execution.
Pointcut
A Pointcut is a predicate that helps match an Advice to be applied by an Aspect at a
particular JoinPoint.
We often associate the Advice with a Pointcut expression, and it runs at
any Joinpoint matched by the Pointcut.
Advice
Now let’s look at how we can wire a Business Object to an Aspect with an After-Returning
advice.
Below is the config excerpt that we’d place in a standard Spring config in
the “<beans>” tag:
<bean id="sampleAdder" class="org.baeldung.logger.SampleAdder" />
<bean id="doAfterReturningAspect"
class="org.baeldung.logger.AdderAfterReturnAspect" />
<aop:config>
<aop:aspect id="aspects" ref="doAfterReturningAspect">
<aop:pointcut id="pointCutAfterReturning" expression=
"execution(* org.baeldung.logger.SampleAdder+.*(..))"/>
<aop:after-returning method="afterReturn"
returning="returnValue" pointcut-ref="pointCutAfterReturning"/>
</aop:aspect>
</aop:config>
As we can see, we defined a simple bean called simpleAdder, which represents an instance of
a Business Object. In addition, we created an instance of an Aspect
called AdderAfterReturnAspect.
You are here
Home > Spring Boot >
Now you might have a question in your mind: ‘What are these repetitive lines
of code?’. In Simple terms the lines of code which we write to implement
Logging, Security, Transaction Management, Data Transfer etc. We also call
them ‘Cross-Cutting Concerns’. Furthermore, let’s talk about our topic ‘How to
implement AOP in Spring Boot Application?’ step by step as a whole.
Ad
Table of Contents
What Can You Expect from This Article?
What is Cross-Cutting Concern?
What is AOP (Aspect Oriented Programming)?
What is Spring AOP?
What is an Aspect in AOP?
What is an advice?
What is a Pointcut?
What is a JoinPoint?
What is a Target?
What is a Proxy?
What is Viewing?
What are the different ways to implement AOP in a Spring application?
How many types of Advice are there?
o Before Advice
o After Advice
o Around Advice
o After Returning Advice
o After Throwing Advice
What is the difference among After, After Returning & After Throwing
Advices?
What are different annotations used in AOP ?
o @Aspect
o @Pointcut
o @Before
o @After
o @AfterReturning
o @AfterThrowing
o @Around
Examples of Pointcut Expressions
Brainstorming Exercise to revise all types of Pointcut Expressions
How to implement AOP in Spring Boot Application?
o Tools & Technologies used in this example project
o Step#1 : Create a Spring Boot Starter Project in STS(Spring Tool Suite)
o Step#2 : Update pom.xml file
o Step#2 : Apply @EnableAspectJAutoProxy on Spring Boot Project’s main
class
o Step#3 : Create one Business service class
o Step#4 : Create a Runner class to call & execute business methods
o Step#5 : Create one Aspect class and it’s methods
o Step#5 : Testing the AOP Concepts
output :
How does a Pointcut expression selects a method having a specific annotation?
o Step#1 : Create one custom annotation
o Step#2 : Write one business method and apply custom annotation
o Step#3 : Write one Pointcut and one Advice
o Step#4 : Update Runner class run() method
o Step#4 : Testing Advice on an Annotated method
output :
Summary
ADVERTISEMENT
4) What are various terminologies used in AOP like Advice, Pointcut, JoinPoint,
Target, Proxy, Viewing etc.?
8) Also, What is the difference between After, After Returning and After
Throwing Advices?
12) Last but not the Least, ‘How To Implement AOP In Spring Boot
Application?’.
Spring AOP is a key feature of the Spring Framework that allows us to separate
cross-cutting concerns from the core business logic of our application. Spring
AOP provides a way to modularize these concerns, making our code more
maintainable and improving the separation of concerns in our application.
What is an advice?
An Advice is the actual implementation of an Aspect. Programmatically, advices are the
methods that we write inside an Aspect class to implement the additional features.
What is a Pointcut?
Pointcut is an expression that tells us which business logic method needs advice. However,
one point is to notice that Pointcut never tells us what advice to apply. But in it’s expression,
it only specifies the list of business logic methods where we need to apply advice. In brief it’s
a kind of business logic method selector as a whole. Equally important, a Pointcut expression
allows only two symbols : *(star), .(dot)
What is a JoinPoint?
JoinPoint combines the Pointcut with advices. It connects the selected business logic methods
with the required advices.
What is a Target?
Target is a plain business class without any advice. This is our target which needs advice.
What is a Proxy?
Proxy is a final output of viewing. In fact a proxy object gets created when a business method
mixed with advice is called.
What is Viewing?
In brief Viewing is the process of mixing required advices with business logic methods.
1) Using XML Based Configuration: This method uses XMLs to implement AOP concepts.
However now-a-days very less or negligible people use this style.
2) Using AspectJ Annotations: Here in this method, we completely use annotations.
Moreover AspectJ is an aspect-oriented programming (AOP) library as extension created
at PARC for the Java programming language. It is available in Eclipse Foundation open-
source projects, both stand-alone and integrated into Eclipse. AspectJ has become very
popular and widely used effective standard for AOP by highlighting simplicity and usability
among developers. It uses Java-like syntax, and included IDE integrations for displaying
cross-cutting structures.
How many types of Advice are there?
We have five types of Advice as given below. Types of Advice are on the basis of all
possibilities in execution of a business method.
Before Advice
Before Advice executes before the execution of business method. Once Advice execution
completes method execution will take place automatically.
After Advice
After Advice executes after the execution of business method. Once method execution
completes advice execution will take place automatically.
Around Advice
Around Advice executes in two parts. Some part executes before the execution of business
method, whereas other part executes after the execution of business method.
♦ Although we can have any number of either same type of advice or of different type
connected to a single business method.
What is the difference among After, After Returning & After Throwing Advices?
After Advice mandatorily executes after the execution of business method, but other two
advices may or may not execute after the execution of business method. After Returning
Advice will execute only on successful execution of business method, whereas After
Throwing Advice will execute only on failure in execution of business method.
@Aspect
public class InvoiceAspect { }
@Pointcut
@Pointcut is applied on top of a method in the Aspect class. It has an expression in the
bracket to select the business methods accordingly. Remember that it will only select the
business methods which need advice, but never talks about which advice. For example, below
p1() method represents a pointcut.
@Pointcut("execution(public void
com.dev.spring.aop.service.InvoiceBusinessService.saveInvoice())")
public void p1() { }
Further below Annotations are the types of Advices. An advice must be annotated with any
one type of the advice.
Every Advice Type Annotation must describe related pointcut information in the bracket.
@Before
Method annotated with @Before represents the Before Advice and it will execute before the
execution of business method. For example, below method represents Before Advice with
Pointcut as p1().
@Before("p1()")
public void beginTransaction() {
System.out.println("Transaction begins !");
}
@After
Method annotated with @After represents the After Advice and it will execute after the
execution of business method. For example, below method represents After Advice with
Pointcut as p1().
@After("p1()")
public void completeTransaction() {
System.out.println("Transaction completes !");
}
@AfterReturning
Method annotated with @AfterReturning represents the After Returning Advice and it will
execute after the execution of business method but only if method executes successfully. For
example, below code demonstrates the concept of After Returning Advice with Pointcut as
p1().
@AfterReturning("p1()")
public void commitTransaction() {
System.out.println("Transaction committed !");
}
@AfterThrowing
Method annotated with @AfterThrowing represents the After Throwing Advice and it will
execute after the execution of business method, but only if method fails to execute
successfully. For example, below method represents After Throwing Advice with Pointcut as
p1().
@AfterThrowing("p1()")
public void rollbackTransaction() {
System.out.println("Transaction rolled back !");
}
@Around
Method annotated with @Around represents the Around Advice. It executes in two parts.
Some part executes before the execution of business method, whereas other part executes
after the execution of business method. For example, below method represents Around
Advice with Pointcut as p4().
@Around("p4()")
public void testAroundAdvice(ProceedingJoinPoint pj) throws Throwable {
System.out.println("Executing Before part of business method");
pj.proceed(); // this code will call business method
System.out.println("Executing After part of business method");
}