General configuration and deployment tutorials for AOP projects in Java's Spring framework

  • 2020-05-09 18:38:54
  • OfStack

0. About AOP
Aspect oriented programming (also known as aspect oriented programming) : Aspect Oriented Programming(AOP) is a hotspot in software development and an important part of the Spring framework. The use of AOP can isolate each part of the business logic, thus reducing the coupling between the parts of the business logic, improving the reusability of the program, and improving the efficiency of development.

AOP is a continuation of OOP.

The main functions are: logging, performance statistics, security control, transaction handling, exception handling, and so on.

Main intention is: the log records, performance statistics, security control, transaction processing, the exception handling code division from the business logic code, such as through the separation of these actions, we hope they can be independent to the guidance of business logic method, and then change the behavior does not affect the business logic of the code.

A technique for adding functionality to program dynamic 1 without modifying the source code can be implemented through precompilation and runtime dynamic proxies. AOP is actually a continuation of the GoF design pattern, which is dedicated to decoupling the caller from the called, improving the flexibility and extensibility of the code, and AOP can be said to be a realization of this goal.

Rich support for section-oriented programming is provided in Spring, allowing the development of cohesion by separating the application's business logic from system-level services, such as audit (auditing) and transaction (transaction) management. Application objects implement what they're supposed to do -- complete the business logic -- and that's about it. They are not responsible (even consciously) for other system-level concerns, such as logging or transaction support.

1. Load other external configuration files or properties files in Spring via PropertyPlaceholderConfigurer:
In many javaEE engineering, Spring role is very important, is a management modules and other components of lightweight containers, Spring often need to manage Struts, Ibatis, Hibernate etc, the profile of these open source framework through Spring PropertyPlaceholderConfigurer loading in Spring management, in addition, the database connection information, JNDI connection information properties file can also be through PropertyPlaceholderConfigurer loaded into Spring to management. It can be used as follows:
(1). Load other files into Spring via PropertyPlaceholderConfigurer:
Add the following configuration to the spring configuration file:


<bean class= " org.springframework.beans.factory.config.PropertyPlaceholderConfigurer " > 
    <property name= " locations " > 
       <value>classpath: The file name to load </value> 
        ...  
    </property> 
</bean> 

 
(2). The configuration or properties file to be loaded after the configuration in (1) is loaded into spring. If some information of the loaded configuration or data file is needed at runtime, such as database connection information or JNDI connection information, it can be referenced by using the syntax of the type EL expression, such as:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 

 
Note: it can also be used < context: Property-Placeholderlocation = "classpath: file name to load" / >

2. Dynamic agent of Java:
The underlying implementation principle of Spring's section-oriented programming (AOP) is dynamic proxies, so you must first understand dynamic proxies before you can learn about section-oriented programming.
Dynamic proxy is widely used in Java, and it is one of the most commonly used design patterns in 23 design patterns. The principle of dynamic proxy is that when a target object or its method is called, the system does not return the target object directly, but returns a proxy object through which to access the target object or the method of the target object.
The simple principle of dynamic proxy is as follows:
Client caller -- > Proxy object -- > The target object being invoked.
When a client invokes a proxy object, the proxy object delegates the target object to invoke its business method.
Dynamic proxy is divided into two kinds, dynamic proxy for interface and dynamic proxy for regular classes, the dynamic proxy java is really interface dynamic proxy, cglib for ordinary class dynamic proxy, target javaEE rely on bag and Spring jar package already contains cglib related jar package, so that the agent can also to the ordinary class can be dynamic proxy.
(1).java dynamic proxy for interface:
The dynamic proxy in Java can only dynamically proxy the interface, so the target object must implement the interface, and the proxy object must implement all the interfaces of the target object. The workflow is as follows:

a. Dynamic proxy class writing:
Note: the dynamic proxy must implement the InvocationHandler interface, as well as the following methods:
 


Object invoke(Objectm Proxy instance ,Method Of the interface method invoked on the proxy instance Method The instance ,Object[] Passes in an array of objects with the parameter values of the method call on the proxy instance );  
 

Install JDK documentation, the method is transfer proxy instance, identification method is called java. lang. reflect. Method object and array containing Object type parameters. The invocation handler handles the encoded method call in an appropriate manner, and the result it returns is returned as the result of the method call on the proxy instance.

b. Create proxy object:
 


Proxy.newProxyInstance( Class loader , Class<?>[] An array of interface , Callback the proxy object (1 As is this)) 


When a target object method is called, the proxy object of the target object is created through the method, and the proxy object automatically calls its invoke method to call the target object and returns the result of the call.

(2).cglib for general java class dynamic proxy:
When cglib creates a dynamic proxy, it does not require the target class to implement the interface. Its workflow is as follows:
a. Dynamic agent class preparation:
 


Enhancer enhancer = new Enhancer(); 
// Sets the parent of the target class to itself  
enhancer.setSuperclass( Target class object .getClass()); 
// Set the callback object to the dynamic proxy object itself  
enhancer.setCallback(this); 

 
b. Implementation of MethodInterceptor interface:
Implement the following methods:

Object intercept(Objectm proxy instance, Method instance of the interface method called on the Method proxy instance,Object[] passes in the object array of the parameter values of the method call on the proxy instance,MethodProxy method proxy instance);  
 
Note: cglib can be used for method dynamic proxies as well as class dynamic proxies.

3. Basic concepts of aspect oriented programming (AOP) :
Take a common java method as an example
 


public  The return type   The method name ( The list of parameters ){  - > Surrounding the notification  
     Method preprocessing code    - >    Pre notice  
try{ 
     Method implementation ( Method body ) ... . 
     Method postprocessing code    - >    The rear notice  
}Catch( Exception types  e){ 
     Exception handling...      - >    Exception notification  
}finally{ 
     Finally dealing with agents...      - >    Final notice  
} 
} 


a. Crosscutting concerns, such as the above five (5) the position of the notification, in java object, can the common processing logic with similar position to join such as authentication, transaction, logging processing logic object called crosscutting concerns, such as object-oriented programming (OOP) focus is vertical to the real world of abstract things into the object model of programming. The concerns of aspect oriented programming (AOP) are horizontal. It abstracts the parts of the programming object model that have similar processing logic, which is the crosscutting concern.
b. Section (Aspect) : the crosscutting concerns are abstracted to form a section, which is similar to the class. The two concerns are different, the class is the abstraction of the characteristics of the thing, and the section is the abstraction of the crosscutting concerns.
Join point (Joinpoint) : the point intercepted, the method in Spring, because spring only supports join points of method type, that is, the method intercepted. As in the example above.
d. Pointcut (Pointcut) : the definition of intercepting join points. It is a collection of join points, that is, a collection of 1 series of intercepted methods.
e. Notification (Advice) : what should be done after interception to the join point, that is, the logical processing after interception. The usual operations of permission validation, transaction handling, logging, and so on are defined and completed in the notification.
f. Target object (Target) : the target object of the proxy, that is, the intercepted object. As in the example above.
g. Weaving (Weave) : refers to the process of applying a section to a target object and causing the creation of a proxy object.
h. Introduction (Introduction) : introduction can dynamically add methods and fields to a class at runtime without changing the code.

4. Dependency packages for aspect oriented programming (AOP) supported in Spring:
The following three packages are in the unzipped Spring directory:


lib/aspectj/aspectjweaver.jar
lib/aspectj/aspectjrt.jar
lib/cglib/cglib-nodep-2.1-3.jar

5. When using aspect oriented programming (AOP) in spring, it is necessary to introduce the namespace of aop in the spring configuration file, that is, to add the following configuration:


xmlns:aop= " http://www.springframework.org/schema/aop "  
 " http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd "  

 
Note: two AOP methods are available after Spring2.5, xml based configuration file and java based annotation.
To use annotated aop, you need to add the following support for object annotated aop in the spring configuration file:


<aop:aspectj-autoProxy/> 

 
6. Packaging class of JavaBean -- BeanWrapper:
Spring encapsulates the behavior of an javabean through the BeanWrapper class. You can set and get its property values, such as:


BeanWrapper  Wrapper class object  = BeanWrapperImpl(new  Be wrapper classes ()); 
 Wrapper class object .setPropertyValue( "Property name" , "Attribute value" ); 

 
This way you can set properties to the wrapped class.

7. Annotation-based aspect oriented programming (AOP) development:
(1). Add aop support for annotation methods to the spring configuration file.
(2). Definition section:
Similar to creating a normal class, the "@Aspect" annotation precedes the class to indicate that it is a section.
(3). Add pointcuts in the aspect:
A pointcut is a collection of methods on the intercepted object, usually defined on a method that handles the pointcut in the aspect. Using the "@Pointcut" annotation, the syntax is as follows:


@Pointcut( " execution(* com.test.service..*.*(..)) " ) 
public void anyMethod(){// The method is called the pointcut name  
 Pointcut processing  
} 

 
Grammar parameters:
a. First "*" : indicates that the method being intercepted is an arbitrary return type.
b. com.test.service: here is a simple example of the name of the packet to be intercepted.
c. Two ".. "after the name of the intercepted packet. : indicates that the subpackage below the intercepted packet is also recursively intercepted, that is, the intercepted subpackage.
d. "..." The following "*" : represents all the classes below the intercepted package and its subpackages, that is, the intercepted class.
e. Last "*" : represents all methods in the intercepted class, that is, the intercepted method.
f. "(..) ": represents that the intercepted method receives any parameter, that is, the intercepted parameter.
Note: pointcut definition syntax can support wildcards, but 1 must strictly follow the rules of the syntax. Such as:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
0

Represents the interception of methods beginning with "add" in all classes of the com.test.service package and its subpackages.
(4) add notification in the section:
See the small example in 3 for the notification location in Spring.
"Before" note: pre-notification of declaration.
"@AfterRutruning" note: declare post notification.
"@After" note: declare final notice.
"@AfterThrowing" note: declare the exception notice.
"@Around" note: declare surround notifications.
An example of a notification definition is as follows:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
1

 
Note: wrap-around notifications are slightly different from the other four types of notifications in that they are defined in a special way, both before and after the entire method invocation, so you must use the join point object to tell the join point to continue its logical processing after the wrap-around notification processing. It is defined as follows:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
2

8. Tips for annotation-based aspect oriented programming (AOP) :
(1). Get input parameters:
Such as:


@Before( "Pointcut name  && args( Input parameter name ) " ) 
public void doSomething(String  Input parameter name ){ ... } 

 
(2). Get the return result:
Such as:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
4

 
9. Development of aspect oriented programming (AOP) based on XML:
(1). Define the section class and add notifications in the section class.
(2). Configure the section class in the spring configuration file like normal java class 1.
(3). Add the AOP configuration in the spring configuration file as follows:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
5

 
10. Transaction processing for Spring (declarative transaction processing for Spring) :
Transaction simply refers to one of the most basic operations in the database. The detailed explanation of transaction will be explained in the database related summary later. One of the most important applications of Spring's aspect oriented programming (AOP) is transaction management. Transaction management in Spring2.5 and later supports annotation-based and XML file-based methods:
(1) annotation-based transaction management:
a. Add the namespace for transaction management to the spring configuration file as follows:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
6

 
b. Configure the transaction manager in the spring configuration file as follows:
 


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
7

c. Add a transaction configuration item to the spring configuration file that supports annotation mode as follows:


<tx:annotation-driventransaction-managertx:annotation-driventransaction-manager= " txManager(spring The configured transaction manager in bean the id) " /> 

  d. Using annotation-based transaction management:
In the JavaEE project managed by Spring, the business logic of the transaction needs to be annotated with "@Transactional".

(2). Transaction management based on XML file:
a. Configure the transaction manager in the spring configuration file as follows:


<bean id= " dataSource "  destroy-method= " close "  class= " org.apache.common.dbcp.BasicDataSource " > 
    <!-- Assume that the database connection information is written in an external properties file and has been spring loading --> 
    <property name= " driverClassName "  value= " ${driver} " /> 
    <property name= " url "  value= " ${url} " /> 
    <property name= " username "  value= " ${username} " /> 
    <property name= " password "  value= " ${password} " /> 
</bean> 
9

  b. Add the aspect of business management to the spring configuration file as follows:


<aop:config> 
    <!-- Configure the transaction pointcut --> 
    <aop:pointcut id= " transactionPointcut "  
Expression= " execution(* com.test.service..*.*(..)) " /> 
<!-- Configure transaction notifications -->   
<aop:advisor advice-ref= " txAdvice "  pointcut-ref= " transactionPointcut " /> 
</aop:config> 
 
c. Add transaction handling features for transaction notifications in the spring configuration file as follows:

 
<tx:advice id= " txAdvice "  transactionManager= " txManager " > 
    <tx:attributes> 
       <!-- Here is an example of a get The initial query method is set to read-only and does not support transactions --> 
       <tx:method name= " get* "  read-only= " true "  propagation= " NOT_SUPPORTED " /> 
       <!-- The other methods are set to spring The default behavior of things --> 
       <tx:method name= " * " /> 
    </tx:attributes> 
</tx:advice> 


Related articles: