Giter Site home page Giter Site logo

spring-source-weaving-example's Introduction

Build Status Quality Gate Technical debt ratio Coverage

Spring Boot Source Weaving (Compile time) Example with AspectJ

This is an example of Spring Boot source weaving (compile time) with AspectJ.

Source Weaving

AspectJ source weaving is compile-time weaving when all source code is available including annotation class, aspect class, and target class.

The AspectJ compiler (ajc) processes the source code and generates woven byte code. All the source code should be present together at the compile time.

When do you need source weaving?

  1. Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.

  2. For JDK proxies, only public interface method calls on the proxy can be intercepted. With CGLIB, public and protected method calls on the proxy will be intercepted, and even package-visible methods if necessary.

You can find more here.

In other words,

  1. Any call to a private method will not be intercepted. Please refer to the second point mentioned above.

  2. Any call to method methodB of class ClassX* from methodA of class ClassX will not be intercepted since they belong to the same target object. Please refer to the first point above.

AspectJ source weaving will help you get past the above limitations posed by Spring AOP.

Project Description

  1. A CustomAnnotation annotation to intercept any method.
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {

    String description() default "";
}
  1. A CustomAnnotationAspect aspect to intercept any method marked with @CustomAnnotation. It prints out the name of the intercepted class and method.
@Component
@Aspect
@Slf4j
public class CustomAnnotationAspect {

    @Before("@annotation(anno) && execution(* *(..))")
    public void inspectMethod(JoinPoint jp, CustomAnnotation anno) {
        log.info(
                "Entering CustomAnnotationAspect.inspectMethod() in class "
                        + jp.getSignature().getDeclaringTypeName()
                        + " - method: " + jp.getSignature().getName()
                        + " description: " + anno.description());
    }
}
  1. The BookService class is the example where the @CustomAnnotation is used. The private method validateRequest is called from create method. The create method is annotated with Spring's @Transactional annotation.
@Service
@Slf4j
public class BookService {

    private BookRepository repository;

    @Autowired
    public BookService(BookRepository repository) {
        this.repository = repository;
    }

    @Transactional
    public Book create(BookRequest request) {
        Book entity = validateRequest(request);
        return repository.save(entity);
    }

    public Book read(UUID id) {
        return repository.getOne(id);
    }

    @CustomAnnotation(description = "Validates book request.")
    private Book validateRequest(BookRequest request) {
        log.info("Validating book request!");

        Assert.notNull(request, "Book request cannot be empty!");
        Assert.notNull(request.getTitle(), "Book title cannot be missing!");
        Assert.notNull(request.getAuthor(), "Book author cannot be missing!");

        Book entity = new Book();
        entity.setTitle(request.getTitle());
        entity.setAuthor(request.getAuthor());

        return entity;
    }
}

Dependency Requirements

AspectJ Runtime Library

Annotation such as @Aspect, @Pointcut, and @Before are in aspectjrt.jar. The aspectjrt.jar and must be in the classpath regardless of whether the aspects in the code are compiled with ajc or javac.

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.13</version>
</dependency>

AspectJ Weaving Library

The aspectjweaver.jar contains the AspectJ wevaing classes. The weaver is responsible for mapping crosscutting elements to Java constructs.

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.13</version>
</dependency>

AspectJ Maven Plugin

The aspectj-maven-plugin plugin is used for weaving AspectJ aspects into the classes using ajc (AspectJ compiler) during compile time.

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>aspectj-maven-plugin</artifactId>
   <version>1.11</version>
   <configuration>
      <showWeaveInfo>true</showWeaveInfo>
      <source>1.8</source>
      <target>1.8</target>
      <complianceLevel>1.8</complianceLevel>
      <Xlint>ignore</Xlint>
      <forceAjcCompile>true</forceAjcCompile>
      <sources />
      <weaveDirectories>
         <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
      </weaveDirectories>
   </configuration>
   <executions>
      <execution>
         <goals>
            <goal>compile</goal>
            <goal>test-compile</goal>
         </goals>
      </execution>
   </executions>
   <dependencies>
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjrt</artifactId>
         <version>1.8.13</version>
      </dependency>
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjtools</artifactId>
         <version>1.8.13</version>
      </dependency>
   </dependencies>
</plugin>

Lombok Maven Plugin (Optional)

The lombok-maven-plugin is required only if any of the classes uses Lombok annotations. The Lombok annotated classes are delomboked before compiled with the ajc.

<plugin>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok-maven-plugin</artifactId>
   <version>1.16.20.0</version>
   <executions>
      <execution>
         <phase>generate-sources</phase>
         <goals>
            <goal>delombok</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      <addOutputDirectory>false</addOutputDirectory>
      <sourceDirectory>src/main/java</sourceDirectory>
      <encoding>UTF-8</encoding>
   </configuration>
</plugin>

Build

To build the JAR, execute the following command from the parent directory:

mvn clean install

Run

Run the executable jar from the command to start the application,

java -jar spring-source-weaving-example-1.0.0.jar

Usage

Once the application starts up at port 8080, you can access the swagger UI at http://localhost:8080/swagger-ui.html. From the UI, you can create and retrieve book entities.

Once you create a book entity, you should notice the following message on the terminal:

2018-02-08 09:46:55.429  INFO 29924 --- [nio-8080-exec-1] c.basaki.aspect.CustomAnnotationAspect   : Entering CustomAnnotationAspect.inspectMethod() in class com.basaki.service.BookService - method: validateRequest description: Validates book request.
2018-02-08 09:46:55.429  INFO 29924 --- [nio-8080-exec-1] com.basaki.service.BookService           : Validating book request!

spring-source-weaving-example's People

Contributors

indrabasak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.