By kswaughs | Friday, February 12, 2016

Spring AOP with annotations

Spring AOP allows us to add multiple aspects without changing the actual business logic code of java files like controllers, service etc.

In this example, I am going to explain you how to apply aspects in a spring based application using annotations.

I am adding these examples on top of the existing spring application that is explained in below articles.

Step 1: Add @EnableAspectJAutoProxy annotation to the spring configuration file.

SpringWebConfig
package com.kswaughs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import com.kswaughs.interceptor.TransactionInterceptor;

@EnableAspectJAutoProxy
@EnableWebMvc 
@Configuration
@ComponentScan({ "com.kswaughs.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
 
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/jsps/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
  
        registry.addInterceptor(new TransactionInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/phones");
    }
}

Step 2: Create an Aspect class and define the pointcut expression where you want to apply this aspect. In this example, I am applying this aspect after PhoneService.getPhoneDetails() method is executed.

PhoneLogAspect
package com.kswaughs.web.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PhoneLogAspect {

    @AfterReturning(
        pointcut = "execution(* com.kswaughs.web.service.PhoneService.getPhoneDetails(..))",
        returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {

        System.out.println("******");
        System.out.println("logAfterReturning() is running!");
        System.out.println("Method Intercepted : " + joinPoint.getSignature().getName());
        System.out.println("Method returned value is : " + result);
        System.out.println("******");
    }
}

Below is the output printed in console when phone details page is rendered to the browser.

output:
******
logAfterReturning() is running!
Method Intercepted : getPhoneDetails
Method returned value is : Phone [id=2, name=Nokia Lumia, price=12,000]
******

Maven dependencies

pom.xml
<dependencies>
    <!-- Spring framework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- AspectJ -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.6.11</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.2</version>
    </dependency>
    <!-- JSTL for jsp pages -->
        <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <!-- Servlet API jars -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Recommend this on


1 comment: