Introduction advice

In enterprise application, sometimes, the developers come across situations where they need to introduce a set of new functionalities, but without changing the existing code. Using introduction, all the interface implementations do not necessarily need to be changed, as it becomes very complex. Sometimes, developers work with third-party implementations where the source code is unavailable; introduction plays a very important role here. Developers may have an option to use the decorator or adapter design pattern so that the new functionalities can be introduced. However, method-level AOP helps in achieving introduction of new functionalities without writing decorators or adapters.

Introduction is an advisor, which allows introducing new functionalities while handling the cross-cutting concerns. To introduce the new implementation, developers have to either use <aop:declare-partents> for schema-based configuration, or @DeclareParents if using annotation-based implementations.

Using schema to add introduction, the <aop:declare-parent> configuration declares a new parent for the bean that is being advised. The configuration is as follows:

<aop:aspect> 
  <aop:declare-parents types-matching="" implement-interface="" 
     default-impl="" /> 
</aop:aspect> 

The attributes used in the configuration are as follows:

  • types-matching: This specifies the matching type of the bean getting advised
  • implement: This is the newly introduced interface
  • default-impl:This is the class that implements the newly introduced interface

In case of using annotations, the developers can use @DeclareParents, which is equivalent to the <aop:declare-parents> configuration. The @DecalreParents annotation will be applied to the property, which is the new interface that has been introduced. The syntax of @DeclareParents is shown as follows:

@DeclareParents(value="" , defaultImpl="") 

The attributes used in the annotations are as follows:

  • value: It specifies the bean to be introduced with the interface
  • defaultImpl: It is equivalent to default-impl of the <aop:declare-parent> attribute, which specifies the class that provides implementation of the interface

Let's use introduction advice in the JdbcTemplate application. The BookDAO class doesn't have the method to get a description of the book, so let's add it. We will use Ch03_JdbcTemplate as the base application. Follow these steps to use introduction:

  1. Create a new Java application, and name it Ch04_Introduction.
  2. Add all the jars required for Spring core, Spring-jdbc, and Spring AOP, as we did in earlier applications.
  3. Copy the com.packt.ch03.beans package.
  4. Create or copy com.packt.ch03.dao with the BookDAO.java and BookDAO_JdbcTemplate.java classes.
  5. Copy connection_new.xml in the classpath, and delete the bean having id as namedTemplate.
  1. Create a new BookDAO_new interface in the com.packt.ch03.dao package, shown as follows, to declare the getDescription() method:
public interface BookDAO_new { 
  String getDescription(longISBN); 
} 
  1. Create a BookDAO_new_Impl class implementing the BookDAO_new interface, which will deal with JDBC using JdbcTemplate. The code is as follows:
@Repository 
public class BookDAO_new_Impl implements BookDAO_new { 
 
  @Autowired 
  JdbcTemplate jdbcTemplate; 
 
  @Override 
  public String getDescription(longISBN) { 
    // TODO Auto-generated method stub 
    String GET_DESCRIPTION=" select description from book where ISBN=?"; 
    String description= jdbcTemplate.queryForObject(GET_DESCRIPTION,  
      new Object[]{ISBN},String.class); 
    return description; 
  } 
} 
  1. Create an Aspect MyIntroductionAspect class in the com.packt.ch04.aspects package, which will introduce the new interface to use the getDescription() method. The code is shown as follows:
@Aspect 
public class MyIntroductionAspect { 
  @DeclareParents(value="com.packt.ch03.dao.BookDAO+",  
     defaultImpl=com.packt.ch03.dao.BookDAO_new_Impl.class) 
  BookDAO_new bookDAO_new; 
} 

The annotation provides the introduction of BookDAO_new, which has additional methods than those available in the BookDAO interface. The default implementation to be used for introduction is BookDAO_new_Impl. Follow these steps to register the aspect and enable it from XML:

  1. Register the aspect in connection_new.xml like this:
<bean class="com.packt.ch04.aspects.MyIntroductionAspect"></bean> 
  1. Add the following configuration to enable autoproxy:
<aop:aspectj-autoproxy proxy-target-class="true"/> 

By default, Spring uses interface-based proxy creation. However, sometimes, the classes don't implement the interface. In such situations, the proxy-target-class attribute is used to force the proxy to be created based on the class. Copy or create MainBookDAO_operation.java to test the code. Use the getDescription() method to find the description of the code. The statements in bold in the following code are the additional statements to add:

public class MainBookDAO_operations { 
  public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    ApplicationContext context=new 
         ClassPathXmlApplicationContext("connection_new.xml"); 
    BookDAO bookDAO=(BookDAO)  
      context.getBean("bookDAO_jdbcTemplate"); 
    //add book 
    int rows=bookDAO.addBook(new Book("Java EE 7 Developer  
      Handbook", 97815674L,"PacktPub  
      publication",332,"explore the Java EE7  
      programming","Peter pilgrim")); 
    if(rows>0) 
    { 
      System.out.println("book inserted successfully"); 
    } 
    else 
      System.out.println("SORRY!cannot add book"); 
 
    //update the book 
    rows=bookDAO.updateBook(97815674L,432); 
    if(rows>0) 
    { 
      System.out.println("book updated successfully"); 
    }else 
    System.out.println("SORRY!cannot update book"); 
    String  desc=((BookDAO_new)bookDAO).getDescription(97815674L);
System.out.println(desc); //delete the book boolean deleted=bookDAO.deleteBook(97815674L); if(deleted) { System.out.println("book deleted successfully"); }else System.out.println("SORRY!cannot delete book"); } }

As BookDAO doesn't have getDescription(), in order to use it, we will need to cast the obtained object to BookDAO_new.

  1. On execution, we will get the output on the console as follows:

 

The output clearly shows that we are able to introduce the getDescription() method without changing BookDAO and its implementations.

..................Content has been hidden....................

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