Wednesday, May 17, 2017

Spring AOP

Introduction

Spring AOP (Aspect-oriented programming) framework helps to decouple cross-cutting concerns form the objects that they affect.Using Spring framework cross-cutting concerns can now be modularized into special objects called "Aspects". This concept helps to reduce boilder plate codes and helps to implement separation of concerns. Transactions, Security, Logging are some examples of cross-cutting concerns.

Aspect

This can be define as a centralized module which has a set of APIs providing cross-cutting concerns across the application.

Aspect = advice + pointcut;

Advice

Aspects have a purpose- a job that they are meant to do.In AOP the job of an aspect is called "advice". Advice defines both "what" and "when" of an aspect.
"what" : what is the job  "when" : when to perform job. Should it apply before or after method invoke?

joinpoint

Your application may have thousands of opportunities for advice to be applied.These opportunities are known "joinpoints". So a joinpoint is a point in the execution of the application where an aspect can be plugged in.

pointcut

A subset of joinpoint actually needs to be advised by an aspect. If advice defines "what" and "when" of aspects then pointcut defines the "where". Typically they are defined within Advice annotations.
i.e

@Before("execution(void doSomething())")

pointcut examples 

"execution(void doSomething())" => apply on exactly "void doSomething()" method
"execution(* doSomething())" => apply on "doSomething()" regardless return type
"execution(* doSomething(..))" => apply on "doSomething" regardless of return type and any number of parameters and any type.
"execution(* doSomething(*))" => apply on "doSomething" regardless of return type but exactly one argument of any type.
"execution(* com.rahal..*Service.*(..))" => execute any method, class name ends with Service in package com.rahal or sub packages.
"execution(* *..*Service.*(..))" => execute any method, class name ends with Service in any package or sub packages.
"execution(@annotation.Trace * *(..))" => Method must be annotated. Note annotation.Trace is fully qualified name of the annotation.
 "execution(* (@annotation.Trace *).*(..))" => Class must be annotated.
 "execution(void doSomething(..) || void doThisThing())" => you can use OR, AND operators

Code example

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.apache.log4j.Logger;

@Component // define as a spring bean
@Aspect    // define this bean as aspect
public class TracingAspect {
   
    boolean enteringCalled = false;
    private final Logger log = Logger.getLogger(this.getClass());
   
    public boolean isEnteringCalled(){
        return enteringCalled;
    }
   
    /*
     * Follwing method is an example of Aspect. Method body defines "what"
     * and @Before define "when" to execute Aspect. "execution(void doSomething())"
     * define the pointcut("where" to apply)
     */
    @Before("execution(void doSomething())")
    public void entering(JoinPoint joinPoint){
        enteringCalled = true;
        log.trace("***************** entering " + joinPoint.getStaticPart().toString());
    }
}

Target

A target is the object that is being adviced. Without AOP this object would have to contain
its primary logic + cross-cutting concerns. With AOP traget object is free to focus on its primary logic.

Proxy


A proxy is the object created after applying advice to the target object. As far as outside client objects are
concerned , the target object (pre-AOP) and the proxy object(post-AOP) are the same .

In Spring AOP, 4 type of advices are supported :

1.Before advice – Run before the method execution
2.After advice – Run after the method exection
3.After returning advice – Run after the method returns a result successfully
4.After throwing advice – Run after the method throws an exception
5.Around advice – Run around the method execution, combine all advices above. Following are the special characteristics about this advice.
    i. Can prevent original method from calling
    ii. Can catch the exception
    iii. Can modify return value

Spring fundamentals

 Spring Container

Techically this is known as ApplicationContext. Specialized implementations are of this
1. ClassPathXmlApplicationContext
2. AnnotationConfigApplicationContext
3. GenericWebApplicationContext
......

Primary responsiblities of spring container are
1. Inversion of Control
2. Dependency injection

Configuring Spring Container

1. XML configuration (sample)
2. Java Annotations (sample)
3. Java Source Code (sample)

 Inversion Of Control

A process of externalizing the construction and mangement of objects. Means you outsource control of objects to an object factory.

Creation of objects are configurable not hard-coded.

Dependency Injection

Decouple conventional depedency relationship between objects. Basically you outsource the construction of object with necessary to third party component. This third party component will inject necessary "dependencies" and construct your object and send back to you.

For example if you want to have a car you simply ask for car manufacturing company. Then company will "inject" necessary "dependencies" for car like engine, tires, body, .. and build the car for you.

 

Spring annotations

To enable the annotation is spring, we need to define followings in configuration file.
1. namespace , schema and xsd location for context
2. enable annotation
3. where to scan annotations

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    XML:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.rahal"/>
</beans>

Steretyping Annotations

These annotations are used to stereotype classes with regard to the application tier that they belong to. Classes that are annotated with one of these annotations will automatically be registered in the Spring application context if <context:component-scan> is in the Spring XML configuration.



1. @Component - generic stereotype for any Spring-managed component
2. @Service       - stereotype for persistence layer
3. @Repository  - stereotype for service layer
4.@Controller    - stereotype for presentation layer (spring-mvc)

1. @scope 

Declare scope for the beans. Five types of scopes.
  1. singleton (default) : Return a single bean instance per Spring IoC container
  2. prototype : Return a new bean instance each time when requested
  3. request : Return a single bean instance per HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
  4. session : Return a single bean instance per HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
  5. globalSession : Return a single bean instance per global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
i.e     @Scope("prototype")
          public class CustomerService
          { 

           }

2. @Autowired

Spring container can autowire relationships without using complex configurations .

Autowiring Modes (Xml Configuration)

ByType : If bean has autowire="byType"  in bean configuration then container tries to match and wire property, if its type match with exactly one bean defined in configuration. If more than such beans defined in configuration fatal exception will be thrown.
 

ByName : Applies to property setter method. If bean has autowire="byName"  in bean configuration then container looks for the property names of the bean. Then it tries to match and wire its properties with beans defined by the same name in configuration file.


Constructor : Similar to byType, but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, fatal error will be thrown.

Autowiring annotation (@Autowired)

When spring container finds @Autowired it will scan though stereotype annotation and tries to bind appropriately.
  1. On Properties ( ByType )
    i.e   @Autowired
           private CustomerRepository customerRepository;
  2. On Setters ( ByType )
  3. On Constructors (Constructor)

3. @Qualifier

As in @autwired, when spring use 'byType' mode, dependencies are looked for property class types. But if there are two or more beans for same type class spring will throw an error. To resolve this confilict we use @Qualifier.
(sample)

4. @Configuration and @Bean

These two annotations help to enable java-base configuration (without using any xml). Annotation a class with @Configuration imply to the spring container that the class is used to define beans. When spring container find @Bean defined under the @Configuration , it will create Object and register in spring context.
(sample)

 Property Files

Spring provide handy way of injecting properties defined in property file to bean properties. To do that add following configurations into configuration xml

1. <context:annotation-config/>
2. <context:property-placeholder location="filename"/>

Use @Value annotation to inject  values

i.e @Value("${dbUsername}")
     private String dbUserName;


Property file should be in classpath and should have key=value structure.