I. AOP programming Overview
The entry of object-oriented programming technology into the mainstream of software development has a great impact on the way software is developed. developers can use a set of entities and the relationships between these entities to express the system image, this allows them to design larger and more complex systems with shorter development cycles than before. The only problem with OO development is that it is static in nature, and minor changes in requirements may have a significant impact on the development progress.
Aspect-Oriented Programming (AOP) is a supplement and improvement to OO technology. It allows developers to dynamically modify static OO models and construct a system that can continuously grow to meet new requirements, just as objects in the real world constantly change themselves in their lifecycles, applications can also have new features in development.
For example, many people may have the experience of using Servlet as the entry point when developing simple Web applications, that is, using Servlet to receive HTML form input and return it to users after processing. The Servlet at the beginning may be very simple, with only a few pieces of code that meet your needs. However, with the implementation of "second requirement", such as exception handling, security, logs, and other functions, the size of the Code will increase to three or four times. The reason is that the "second requirement" is because the basic function of Servlet is to accept and process user requests. For this purpose, log, security, and other mechanisms are not essential.
AOP allows you to dynamically change the static model of OO. You do not need to modify the original static model or add the Code required to meet the second requirement (in fact, even the original source code is not required ). What is even more surprising is that the Code added later can often be concentrated in one place, instead of spreading the code added later to the entire model just like OO.
Ii. Basic Terms
Before introducing the AOP development instance, let's take a look at several standard AOP terms to better understand relevant concepts.
Cross-cutting concern
In the OO model, although most classes only have a single and specific function, they usually have a second requirement with other classes. For example, when a thread enters or leaves a method, we may need to record logs both in the class at the data access layer and in the class at the UI Layer. Although the basic functions of each class are extremely different, the code used to meet the second requirement is basically the same.
Advice
It refers to the additional code that you want to apply to the existing model. In this example, 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 must be used. In this example, a Point-cut occurs when the thread enters a method, and another Point-cut occurs when the thread leaves the method.
Aspect
The combination of Point-cut and advice is called aspect. In the following example, we define a point-cut and add a log (logging) aspect to the appropriate advice.
AOP also has many other features and terminologies, such as Introduction, that is, introducing interfaces, methods, and domains to existing classes-which greatly broadens developers' imagination. However, this article only introduces some of the most basic principles. After you are familiar with the concepts described here, You can further study other features of AOP to see how to use them in your own development environment.
Iii. Existing framework
Currently, the most mature and functional AOP framework is AspectJ, which has become the standard followed by most other frameworks. However, AspectJ has taken an extraordinary step, and its implementation adds new keywords to the Java language. Although the new syntax is not difficult to learn, it means we have to change the compiler and re-compile the editor. Only in this way can we adapt to the new syntax. In a large development group, these requirements may be difficult to implement because the entire development team is affected. Due to the changes in the language itself, the learning cycle for the development team to introduce the AOP technology into existing projects is extended.
Now we need a framework that can be easily introduced without affecting the original development and construction processes. There are more than one framework that meets these requirements, such as JBoss AOP, Nanning, and Aspectwerkz (AW ). This document selects Aspectwerkz, because it may be the easiest framework to learn and the framework to integrate into existing projects.
Aspectwerkz is created by Jonas Boner and Alexander re Vasseur. It is one of the fastest and most functional frameworks. Although it lacks some features of AspectJ, it is sufficient to meet the needs of most developers in many situations.
One of the most interesting features of Aspectwerkz is that it can run in two different modes: online mode and offline mode. In online mode, AW directly interferes with the underlying class loading mechanism of the JVM, intercepts all class loading requests, and implements real-time conversion of bytecode. AW provides many options to intervene in the class loading process, and an encapsulation script to replace the bin/java command, this script can automatically generate a set of executable Configurations Based on the Java version and JVM capabilities. For developers, the online mode has many advantages. It can be inserted into any class loader and generate new classes during class loading. That is to say, we do not have to manually modify the class of the application, as long as it is deployed in the usual way. However, the online mode requires additional configuration of the application server, which may be difficult to meet.
In offline mode, two steps are required to generate a class. The first step is to compile with a standard compiler, and the second step is to focus on running the AWcompiler compiler in offline mode so that it can process 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 the offline mode is that the classes generated by AWcompiler can run on any Vm with a JVM of more than 1.3. This mode is used in this article because it does not need to be modified on Tomcat, A slight modification to the construction process can be copied to most existing projects.
Iv. Installation
This article takes a simple Web application as an example. It is compiled with Ant and deployed on the Tomcat 4 + Servlet container. Below we assume that the reader has prepared the above environment, including JVM 1.3 +, and Tomcat is set to automatically deploy the application from the webapps folder, and the WAR is automatically extended to the directory (this is the default operation method of Tomcat, therefore, as long as you have not modified the running mode of Tomcat, the following example can be run directly ). The installation location of Tomcat is % atat_home %.
(1) download aspectwerkz.codehaus.org/from http://apectwerkzand open the ZIP file to the desired location. We will call this location % ASPECTWERKZ_HOME %.
(2) Set % ASPECTWERKZ_HOME % environment variable.
(3) add Aspectwerkz to the path environment variable, that is, set PATH = % PATH %; % ASPECTWERKZ_HOME % inaspectwerkz
(4) download the demo program in this article and put it in the % TOMCAT_HOME % webapps folder.
Worker adds the runtime class of Aspectwerkz to the classpath of Tomcat. You can put its JAR file in the WEB-INFlib folder of the sample application, or % atat_home % commonlib.
5. Compile the sample application
If you want to study the sample application in this article, you can unbind the WAR file and extract its content. You will find an aspectwerkz. xml file under the root directory, which will be copied to the WEB-INF/classes directory when constructing the application. The source files for Servlet and advice are in the WEB-INF/src directory, and there is also an ANT script to build these classes.
You need to compile the sample program later before running it. The procedure is as follows:
(1) In the command line window, go to the directory to unbind the WAR file.
(2) enter the following command to call the AW Compiler: aspectwerkz-offline aspectwerkz. xml WEB-INF/classes-cp % atat_home % commonlibservlet. jar. If later compilation passes smoothly, you should see the following output:
(1 s)
SUCCESS: WEB-INFclasses
There is an ANT task named war in the build file. You can use it to recreate the WAR file.
6. Run the sample application
Start (or restart) Tomcat, and then open http: // localhost: 8080/demo/in the browser /.
After the page is opened, you can see an HTML form with two input boxes, one input name and one input email address. Enter some data and click the button to submit the form. A page displays the contact information and a link pointing to the contact list.
VII. Code Analysis
The JSP page is not analyzed. We are not interested in it now. Let's take a look at the AOPServlet code.
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 is as concise as possible and only contains some essential code, such as creating an object bound to request parameters, but there is no persistent operation, no additional imports is required. It only implements the most basic operations required by Servlet.
However, according to the requirements in the instruction documents, this application must perist all Person objects, so you need to add an aspect to this application. To create this aspect, we first need to create an aspectwerkz. xml file and put it in the directory specified by classpath. This example provides a simple example, which can be opened in the editor.
The first part of aspectwerkz. xml defines the available advice. We can add any number of advice as needed:
<Advice-def name = "persist" class = "example. PersistenceAdvice" deployment-model = "perJVM"/>
In this clip, we define an advice named persist. Its type is example. PersistenceAdvice. The last attribute defines the ranking of the advice. Here its value is perJVM, indicates that only one instance of the advice is created in each JVM. For more information about the deployment mode, see the document of Aspectwerkz.
The second part begins to define aspect. Here we map advice to the place where point-cut creates 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>
Next we will analyze this code line by line:
(1) We created an aspect called servlet. If necessary, we can create any number of aspect instances.
(2) In the second row, we created a point-cut called all, which only applies to methods (type = "method ").
(3) In the third row, we use a regular expression to specify where advice is applied. In this example, we point out that the condition for applying advice is: no matter what type the return value is (the first "*"), the name ends with the servlet (* servlet) and contains a doGet method (doGet (...) with any parameters (..)) class in the example package.
(4) In the fourth row, we tell the Aspectwerkz compiler to apply the advice to all point-cut.
Here, we declare that the advice to be used is persist.
Now we know how to map point-cut and advice to create an aspect. Let's take a look at an instance that provides the advice class. In the ing file, we registered an advice of the example. PersistenceAdvice type. below 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, to train it as the most specific type, and the second line may be the most important: because we want to run the method and check the results, therefore, you must call proceed (). In the next part, we capture HttpServletRequest and extract the objects put into the Servlet (Remember, the doGet () method has ended running ).
Finally, we create a class named ContactManager. Its function is to save the Person data to a text file. In fact, it is convenient to save data to XML files, databases, or other persistent storage mechanisms.
One thing you need to know here is that at the design application or prototype stage, Servlet does not know what will happen in the future, and the features of the second stage can be added at any time, because of this, therefore, we say that applications can learn new capabilities in the development process, and it is very convenient to add new functions in the future.
[Conclusion] in the previous example, we tested a simple application, deployed it to Tomcat, and used a browser to run and test its functions. 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 concern, such as security, log, persistence, and buffering. No matter how large the original application is, you can easily add the log function to the entire application within 10 minutes!
I hope that you can go beyond the simple example in this article to see how to use the AOP technology in your project. It will certainly take some time to get familiar with the concept of AOP, but it will certainly get a return. For a medium-sized project, it will save you several weeks, or write thousands of lines of repeated code.