AOP based on aspectwerkz in Java

Time:2022-1-13

  1、 AOP programming overview

The entry of object-oriented programming technology into the mainstream of software development has a great impact on the way of software development. Developers can vividly express the system with a group of entities and the relationship between these entities, which enables them to design larger and more complex systems, and the development cycle is shorter than before. The only problem with OO development is that it is static in nature, and subtle changes in requirements may have a significant impact on the development schedule.

Aspect oriented programming (AOP) is a supplement and improvement to OO technology. It allows developers to dynamically modify the static OO model and construct a system that can continuously grow to meet new requirements. Just like objects in the real world will constantly change themselves in their life cycle, applications can also have new functions in development.

For example, many people must have had the experience of using servlets as the entry point when developing simple web applications, that is, using servlets to receive the input of HTML forms and return them to users after processing. The servlet at the beginning may be very simple, with only the minimum amount of code that just meets the user’s needs. However, with the implementation of the “second requirement”, such as exception handling, security, logging and other functions, the volume of code will increase three or four times. This is called the “second requirement” because the basic function of servlet is to accept and process user requests. For this goal, mechanisms such as logging and security are not essential.

AOP allows you to dynamically change the static model of OO. You don’t have to modify the original static model, and you can also add the code required to meet the second requirement (in fact, you don’t even need the original source code). What’s more amazing is that the later added code can often be concentrated in one place, instead of dispersing the later added code to the whole model as when using OO alone.

  2、 Basic terms

Before introducing AOP development examples, let’s first understand several standard AOP terms in order to better master relevant concepts.

   Cross-cutting concern

In the OO model, although most classes have only a single and specific function, they usually have common secondary requirements with other classes. For example, when a thread enters or leaves a method, we may record logs in both the classes of the data access layer and the classes of the UI layer. Although the basic functions of each class are very different, the code used to meet the second requirement is basically the same.

   Advice

It refers to additional code that you want to apply to an existing model. In this case, it refers to the log code to run when a thread enters or exits a method.

   Point-cut

This term refers to an execution point in an application where the previous cross cutting concern needs to be used. In this example, a point cut appears when the thread enters a method, and another point cut appears when the thread leaves the method.

   Aspect

The combination of point cut and advice is called aspect. In the following example, we add a logging aspect by defining a point cut and giving appropriate advice.

AOP also has many other features and terms, such as introduction, which introduces interfaces / methods / domains into existing classes — it greatly broadens the imagination of developers. However, this article only introduces some basic persistence. After you are familiar with the concepts introduced here, you can further study other features of AOP and see how to use them in your own development environment.

  3、 Existing framework

At present, the most mature and functional AOP framework is AspectJ, which has become the standard followed by most other frameworks. However, AspectJ has also taken an unusual step, and its implementation has added new keywords to the Java language. Although the new syntax is not difficult to learn, it means that we must change a compiler and reconfigure the editor in order to adapt to the new syntax. In larger development teams, these requirements may be difficult to achieve because the entire development team will be affected. Due to the change of the language itself, the learning cycle of the development team introducing AOP technology into the existing project is extended.

What we need now is a framework that can be easily introduced without any impact on the original development and construction process. More than one framework meets these requirements, such as JBoss AOP, Nanning, aspectwerkz (AW). Aspectwerkz is chosen in this article because it is probably the easiest framework to learn and integrate into existing projects.

Aspectwerkz was created by Jonas boner and Alexandre Vasseur. It is one of the fastest and most feature rich frameworks at present. Although it still lacks some functions of AspectJ, it is enough to meet the needs of most developers in many cases.

One of the most interesting features of aspectwerkz is its ability to run in two different modes: online mode and offline mode. In the online mode, aw directly interferes with the underlying class loading mechanism belonging to the JVM, intercepts all class loading requests and implements immediate conversion of bytecode. Aw provides many options to intervene in the class loading process. In addition, there is an encapsulated script instead of bin / Java command, which can automatically generate a set of runnable configurations according to the Java version and JVM capabilities. For developers, online mode has many advantages. It can be inserted into any class loader and generate new classes during class loading. In other words, we don’t have to manually modify the class of the application, just deploy it in the usual way. However, online mode requires additional configuration of the application server, which may sometimes be difficult to meet.

In offline mode, generating classes requires two steps. The first step is to compile with a standard compiler, and the second step is the focus — run the awcompiler in offline mode to process the newly generated classes. The compiler will modify the bytecode of these classes and insert advice in the appropriate point cut according to the definition of an XML file. The advantage of offline mode is that the classes generated by awcompiler can run on any virtual machine above JVM 1.3. This mode is used below in this paper, because it does not need to make any modification to Tomcat. As long as the construction process is slightly modified, it can be copied to most existing projects.

  4、 Installation

This article will take a simple web application as an example, which is compiled with ant and deployed on the Tomcat 4 + Servlet container. Let’s assume that the reader has prepared the above environment, including JVM 1.3 +, and Tomcat is set to automatically deploy applications from the webapps folder and automatically expand the war to the directory (this is the default operation mode of tomcat, so as long as you have not modified the operation mode of tomcat, the following example can be run directly). We will call the Tomcat installation location% Tomcat_ HOME%。

(1) from http://apectwerkz.codehaus.org/ Download aspectwerkz, unpack and compress to the appropriate location. We will call this location% aspectwerkz_ HOME%。

(2) set% aspectwerkz_ Home% environment variable.

(3) add aspectwerkz to the path environment variable, i.e. set path =% path%;% ASPECTWERKZ_ HOME%inaspectwerkz

(4) download the demonstration program of this article and put it into% Tomcat_ Home% webapps folder.

(5) add the runtime class of aspectwerkz to the classpath of Tomcat. You can put its jar file into the web inflib folder of the sample application or% Tomcat_ HOME%commonlib。

    5、 Compiling sample applications

If you want to delve into the example application in this article, you can unpack the war file and extract its content. You’ll find an aspectwerkz in the root directory XML file. When constructing an application, it will be copied to the WEB-INF / classes directory. The source files of servlet and advice are in the WEB-INF / SRC directory, and there is an ant script to build these classes.

You have to post compile the sample program before running it. The following are the specific operation steps:

(1) in the command line window, go to the directory where the war file is unpacked.

⑵ input the following command to call aw compiler: aspectwerkz – offline aspectwerkz xml WEB-INF/classes -cp %TOMCAT_ HOME%commonlibservlet. jar。 If the post compilation passes successfully, you should see the following output:

  ( 1 s )

  SUCCESS: WEB-INFclasses

There is an ant task named war in the build file, which you can use to recreate the war file.

  6、 Run sample application

Start (or restart) Tomcat first, and then open it in the browser http://localhost:8080/demo/ 。

After the page opens, you can see an HTML form with two input boxes, one input name and one input email address. Enter some data, and then click the button to submit the form. A page will appear showing the contact information and a link to the contact list.

  7、 Code analysis

JSP page will not be analyzed, and now we are not interested in it. Let’s look at the code of AOP servlet.

  package example;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AOPServlet extends HttpServlet {
 public void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
  Person person = new Person();
  if (request.getParameter(“name”) != null) {
   person.setName(
   request.getParameter(“name”));
  }
  if (request.getParameter(“email”) != null) {
   person.setEmail(
   request.getParameter(“email”));
  }
  request.setAttribute(“person”, person);
  RequestDispatcher rd =request.getRequestDispatcher(“/view.jsp”);
  rd.forward(request, response);
 }
}

In this example, the servlet code has been as concise as possible and only contains some essential code, such as creating an object binding request parameters, but there is no persistence operation and no additional imports. It only implements the most basic operations that must be implemented as a servlet.

However, according to the requirements of the documentation, the application must specify all objects of person type, so an aspect should be added to the application. To create this aspect, we first create an aspectwerkz XML file and place the file in the directory specified by classpath. This article provides a simple example that you can open and view with an editor.

aspectwerkz. The first part of XML defines the available advice. We can add any number of advice as needed:

  <advice-def name=”persist” deployment-model=”perJVM”/>

In this fragment, we define an advice named persist, whose type is example PersistenceAdvice。 The last attribute defines the exclusivity of the advice. Here, its value is perjvm, which means that only one instance of the advice is created in each JVM (for more instructions on deployment patterns, see aspectwerkz documentation).

The second part starts to define the aspect. Here is where we map the advice to the point cut to create the aspect.

  <aspect name=”servlet”>
  <pointcut-def name=”all” type=”method”
  pattern=”* example.*Servlet.doGet(..)”/>
  <bind-advice pointcut=”all”>
  <advice-ref name=”persist”/>
  </bind-advice>
  </aspect>

Let’s analyze this code line by line:

(1) we created an aspect called servlet. If necessary, we can create any number of aspects.

(2) in the second line, we create a point cut called all, which is only applicable to methods (type = “method”).

(3) in the third line, we use a regular expression to specify where to apply advice. In this example, we point out that the condition for applying advice is: no matter what the type of return value is (the first “*”), the name ends with servlet (* servlet) and contains a doget method with arbitrary parameters (doget (..)) The class in the example package of.

(4) in the fourth line, we tell the aspectwerkz compiler to apply the following advice to all point cuts.

(5) here we declare that the advice to be used is persist.

Now that we know how to map point cut and advice to create an aspect, let’s take a look at an example of a class that provides advice. In the mapping file, we registered an example Advice of persistenceadvice type. The following is the source code of this type:

  package example;

import javax.servlet.http.*;
import org.codehaus.aspectwerkz.advice.*;
import org.codehaus.aspectwerkz.joinpoint.*;

public class PersistenceAdvice extends AroundAdvice {
 public PersistenceAdvice() {
  super();
 }
 public Object execute(final JoinPoint joinPoint)
 throws Throwable {
  MethodJoinPoint jp =(MethodJoinPoint) joinPoint;
  final Object result = joinPoint.proceed();
  Object[] parameters = jp.getParameters();
  if (parameters[0] instanceof HttpServletRequest) {
   HttpServletRequest request =(HttpServletRequest) parameters[0];
   if (request.getAttribute(“person”) != null) {
    Person contact =(Person) request.getAttribute(“person”);
    ContactManager persistent = new ContactManager();
    String fileName =(request.getRealPath(“/”)+”contacts.txt”);
    persistent.save(contact, fileName);
   }
  }
  return result;
 }
}

The first line of the execute () method is easy to understand, that is, try to stereotype it into the most specific type. The second line is perhaps the most important: because we want to run the method and check the results, we must call proceed (). In the next part, we capture HttpServletRequest and extract the objects put by the servlet (remember, the doget () method has finished running at this time).

Finally, we create a class named contactmanager, whose function is to save the data of person to a text file. In fact, it is also convenient to save data to XML files, databases, or other persistent storage mechanisms.

One thing to master here is that in the stage of designing applications or building prototypes, the servlet does not know what changes will happen in the future. The functions in the second stage can be added at any time. Because of this, we say that the application can learn new capabilities in the development process, and it is very convenient to add new functions in the future.

[Conclusion] we tested a simple application in the previous example, deployed it to tomcat, and ran and tested its function with a browser. Although the application itself has no practical use, it demonstrates and confirms some very useful concepts. Imagine that you can quickly build a prototype, and then introduce cross cutting concerns such as security, logging, persistence and buffering. No matter how large the original application is, you will be able to easily add logging to the whole application in ten minutes!

I hope you can go beyond the simple examples in this article to see how to adopt AOP technology in your own projects. It takes time to get familiar with the concept of AOP, but it will certainly pay off. For a medium-sized project, it will save you weeks or write thousands of lines of repetitive code.