Annotation-based aspects

An aspect can be declared as a Java class annotated with AspectJ annotations to support the writing of pointcuts and advices. Spring AspectJ OP implementations provide the following annotations to write aspects:

  • @Aspect: This is used to declare a Java class as an Aspect.
  • @Pointcut: This is used to declare the pointcut expression using the AspectJ expression language.
  • @Before: This is used to declare the before advice that is applied before the business logic (B.L.) method. The @Before annotation supports the following attributes:
    • value: This is the name of the method annotated by @Pointcut
    • argNames: This is to specify the name of the parameters at join point
  • @After: This is used to declare the After advice, which is applied after the B.L. method before returning the result. The @After annotation also supports the same attributes as that of the @Before advice.
  • @AfterThrowing: This is used to declare the after throwing advice, which is applied after the exception is thrown by the B.L. method. The @ AfterThrowing annotation supports the following attributes:
    • pointcut: This is the pointcut expression to select the join point
    • throwing: This is the name of the argument that will be bound with exception thrown by the B.L. method
  • @AfterReturning: This is used to declare the after returning advice, which is applied after the B.L. method, but before the result is returned. The advice helps in getting the value of the result from the B.L. method. The @AfterReturning annotation supports the following attributes:
    • pointcut: This is the pointcut expression to select the join point
    • returning: This is the name of the argument bounded with the value returned from the B.L. method
  • @Around: This is used to declare the around advice, which is applied before as well as after the B.L. method.The @Around annotation supports the same attribute as that of the @Before or @After advice.

We must declare the configuration in the Spring context to enable proxy creation of the bean. The AnnotationAwareAspectJAutoproxyCreator class helps in this. We can register the class in a simple way for @AspectJ support by including the following configuration in the XML file:

<aop:aspectj-autoproxy/> 

To add the preceding configuration, don't forget to configure the aop namespace as discussed earlier. We can perform the following steps to declare and use the annotation-based aspect:

  1. Declare a Java class, and annotate it by @Aspect.
  2. Add the method annotated by @Poincut to declare the pointcut expression.
  3. Add the methods for advices, and annotate them by @Before, @After, @Around, and so on, as per the requirements.
  4. Add the configuration for the aop namespace.
  5. Add the aspect in the configuration as a bean.
  6. Enable the auto-proxy support in the configuration.

Let's add the annotation-based aspect in the JdbcTemplate application. Follow the steps in part 1 and 2 from the earlier application, where we did logging aspects to create a base application named Ch04_JdbcTemplate_LoggingAspect_Annotation. You can refer to the Ch04_JdbcTemplate_LoggingAspect application. Now use the following steps to develop an annotation-based logging aspect:

  1. Create a MyLoggingAspect class in the com.packt.ch04.aspect package.
  2. Annotate it with @Aspect.
  3. Add a data member of type org.apache.log4j.Logger in it.
  4. Add the beforeAdvise()method to apply advice before the business logic method, addBook(). Annotate it with @Before. The code is as follows:
@Aspect 
public class MyLoggingAspect { 
  Logger logger=Logger.getLogger(getClass()); 
  @Before("execution(* com.packt.ch03.dao.BookDAO.addBook(
com.packt.ch03.beans.Book))") public void beforeAdvise(JoinPoint joinPoint) { logger.info("method will be invoked :- "+joinPoint.getSignature()); } }
  1. Edit connection_new.xml to add the aop namespace if you haven't already done that.
  2. Add a bean for MyLoggingAspect, as follows:
<bean id="logging" class="com.packt.ch04.aspects.MyLoggingAspect"/> 

An alternative to the preceding configuration will annotate MyLoggingAspect by the @Component annotation:

  1. Enable the AspectJ autoproxy by adding the configuration in connection_new.xml, as follows:
<aop:aspectj-autoproxy/> 
  1. Execute MainBookDAO-operation.java to get the log on the console, as follows:
23742 [main] INFO  com.packt.ch04.aspects.MyLoggingAspect  - method will be invoked :-int com.packt.ch03.dao.BookDAO.addBook(Book) 

To write the pointcut expression for each advice may be a tedious and an unnecessarily repetitive task. We can declare the pointcut separately in a marker method, as shown in the following code snippet:

@Pointcut(value="execution(* com.packt.ch03.dao.BookDAO.addBook(com.packt.ch03.beans.Book))") 
public void selectAdd(){} 

Then, refer to the preceding code from the advice method. We can update the beforeAdvise () method as follows:

@Before("selectAdd()") 
public void beforeAdvise(JoinPoint joinPoint) { 
  logger.info("method will be invoked :- 
  "+joinPoint.getSignature()); 
} 
  1. Now that we know the basis of Aspect declaration, let's add the methods for other Aspect and pointcuts, as already discussed in the aspect declaration using XML. The Aspect will be shown as follows:
@Aspect 
public class MyLoggingAspect { 
  Logger logger=Logger.getLogger(getClass()); 
 
  @Pointcut(value="execution(
*com.packt.ch03.dao.BookDAO.addBook(
com.packt.ch03.beans.Book))") public void selectAdd(){ } @Pointcut(value="execution(* com.packt.ch03.dao.BookDAO.*(..))") public void selectAll(){ } // old configuration /* @Before("execution(*com.packt.ch03.dao.BookDAO.addBook(
com.packt.ch03.beans.Book))") public void beforeAdvise(JoinPoint joinPoint) { // add the code as we did MyLoggingAspect as we did in XML-based
configuration } */ @Before("selectAdd()") public void beforeAdvise(JoinPoint joinPoint) { // add the code as we did MyLoggingAspect
as we did in //XML-based configuration } @After("selectAll()") public void afterAdvise(JoinPoint joinPoint) { // add the code as we did MyLoggingAspect as we
//did in XML-based configuration } @AfterThrowing(pointcut="execution(*
com.packt.ch03.dao.BookDAO.addBook(
com.packt.ch03.beans.Book))", throwing="exception") public void throwingAdvise(JoinPoint joinPoint, Exception exception) { logger.error(joinPoint.getSignature()+" got and exception"
+ " " + exception.toString()); } @Around("selectAdd()") public int aroundAdvise(ProceedingJoinPoint joinPoint) { // add the code as we did MyLoggingAspect as we did in
//XML-based configuration } @AfterReturning(pointcut="selectAll()", returning="val") public void returnAdvise(JoinPoint joinPoint, Object val) { // add the code as we did MyLoggingAspect as we did in
//XML-based configuration } }
  1. Execute MainBookDAO.java to get logging messages on the console.

The class implements the interface by default. JDK's dynamic proxy mechanism will be used for proxy creation. However, sometimes, the target object will not implement the interface, and JDK's proxy mechanism will fail. In such cases, CGLIB can be used for proxy creation. To enable CGLIB proxies, we can write the following configuration:

<aop:config proxy-target-class="true"> 
  <!-aspect configuration--> 
</aop:config> 

Additionally, to force the AspectJ and auto proxy support, we can write the following configuration:

<aop:aspect-autoproxy proxy-target-class="true"/> 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.136.90