0.About AOP
Aspect Oriented Programming (AOP) is a hot topic in software development and an important part of the Spring framework. The various parts of the business logic can be isolated by using AOP, thereby reducing the coupling between the various 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 processing, exception handling, etc.
The main intention is to divide the codes such as logging, performance statistics, security control, transaction processing, exception handling, etc. from the business logic code. By separating these behaviors, we hope to separate them into non-guiding business logic methods, and then change these behaviors without affecting the business logic code.
A technology that dynamically adds functions to programs without modifying the source code can be achieved through precompilation methods and dynamic proxying during runtime. AOP is actually a continuation of the GoF design model. The design model is pursuing decoupling between the caller and the callee, improving the flexibility and scalability of the code. AOP can be said to be an implementation of this goal.
Provides rich support for aspect-oriented programming in Spring, allowing cohesive development by separating the business logic of the application from system-level services such as auditing and transaction management. Application objects only implement what they should do - complete business logic - that's it. They are not responsible (or even aware of) other system-level concerns, such as logging or transaction support.
1. Load other external configuration files or property files in Spring through PropertyPlaceholderConfigurer:
In many javaEE projects, the role of Spring is very important. It is a lightweight container that manages other modules and components. Spring often needs to manage Struts, Ibatis, Hibernate, etc. The configuration files of these open source frameworks are loaded in Spring through Spring's PropertyPlaceholderConfigurer for management. In addition, database connection information, JNDI connection information property files, etc. can also be loaded into Spring through PropertyPlaceholderConfigurer for management. The usage is as follows:
(1). Load other files into Spring through PropertyPlaceholderConfigurer:
Add the following configuration in the spring configuration file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:File name to load</value>… </property> </bean>
(2). The configuration or attribute file to be loaded through the configuration in (1) is loaded into spring. If you also need to use some information about the loaded configuration or data file at runtime, such as using database connection information or JNDI connection information, you can use the syntax of type EL expressions to reference, for example:
<bean id=”dataSource” destroy-method=”close” class=”org.apache.common.dbcp.BasicDataSource”> <!--Suppose the database connection information is written in an external property file and has been loaded by spring--> <property name=”driverClassName” value=”${driver}”/> <property name=”url” value=”${url}”/> <property name=”username” value=”${username}”/> <property name=”password” value=”${password}”/> </bean>
Note: You can also use <context:Property-Placeholderlocation="classpath: File name to load"/>
2. Dynamic proxy for Java:
Spring's underlying implementation principle is dynamic proxy, so you must first understand dynamic proxy before learning aspect-oriented programming.
Dynamic proxy is widely used in Java, and dynamic proxy is one of the classic design patterns that are very commonly used in the design patterns in 23. The principle of dynamic proxy is that when a target object or its method is to be called, the system does not directly return the target object, but returns a proxy object, and accesses the target object or method of the target object through this proxy object.
The simple principle of dynamic proxy is as follows:
Client caller --> proxy object --> called target object.
When the client calls the proxy object, the proxy object delegates the target object to call its business method.
Dynamic proxy is divided into two types: dynamic proxy for interfaces and dynamic proxy for ordinary classes. Dynamic proxy in java is a dynamic proxy for real interfaces. cglib is a dynamic proxy for ordinary classes. The target javaEE dependency package and Spring jar package already contain cglib-related jar packages, so you can dynamically proxie the proxy or ordinary classes.
(1).java's dynamic proxy for interfaces:
Dynamic proxy in Java can only be dynamically proxyed for interfaces. Therefore, the target object must implement interfaces, and the proxy object must implement all interfaces of the target object. The workflow is as follows:
a. Dynamic proxy class writing:
Note: Dynamic proxy must implement the InvocationHandler interface, and implement the following methods:
The code copy is as follows:
Object invoke(Objectm proxy instance, Method instance of interface method called on Method proxy instance, Object[] An object array of parameter values passed into the proxy instance);
The documentation for installing JDK is explained. This method is used to pass the proxy instance, identify the java.lang.reflect.Method object that calls the method, and an array of Object type containing parameters. The call handler handles the encoded method call in an appropriate manner, and the result it returns will be returned as the result of the method call on the proxy instance.
b. Create a proxy object:
Proxy.newProxyInstance (class loader, Class<?>[] interface array, callback proxy object (usually this))
When the target object method is called, the proxy object of the target object is created through the method. The proxy object will automatically call its invoke method to call the target object and return the call result.
(2).cglib is dynamic proxy for ordinary java classes:
When cglib creates a dynamic proxy, it does not require the target class to implement an interface. Its workflow is as follows:
a. Dynamic proxy class writing:
Enhancer enhancer = new Enhancer(); //Set the parent class of the target class to its own enhancer.setSuperclass(target class object.getClass()); //Set the callback object to the dynamic proxy object itself enhancer.setCallback(this);
b. Implement the MethodInterceptor interface:
Implement the following method:
Object intercept (Objectm proxy instance, Method instance of interface method called on Method proxy instance, Object[] The object array of parameter values passed to the method call on the proxy instance, MethodProxy method proxy instance);
Note: cglib can not only dynamically proxy for classes, but also dynamically proxy for methods.
3. Basic concepts of Oriented Programming (AOP):
Take an ordinary Java method as an example
public return type method name (parameter list) { ―> Surround notification method preprocessing code -> Pre-notification try{ Method specific implementation (method body)... Method post-processing code -> Post-notification} Catch (Exception type e) { Exception handling... ―> Exception notification} finally{ Last processing agent... ―> Final notification} }
a. Cross-cutting concern: For example, in the above 5 notification locations, in Java objects, these objects with similar common processing logic that can be added to processing logic such as permission verification, thing processing, logging, etc. are called cross-cutting concerns. The focus of object-oriented programming (OOP) is to vertically abstract things in the real world into a programming object model. The focus of aspect-oriented programming (AOP) is horizontal, which abstracts the places similar to processing logic in the programming object model to form a tangent, while the processing logic in the programming object is horizontal tangent focus.
b. Aspect: Abstracting the cross-cutting concerns is to form a section, which is similar to the class. The two have different concerns. Classes are abstractions of the characteristics of things, and sections are abstractions of cross-cutting concerns.
c. Joinpoint: The point that is intercepted is referred to in Spring, because spring only supports method-type connection points, that is, the intercepted method. Method as shown in the above example.
d. Pointcut: refers to the definition of intercepting a connection point, which is a collection of connection points, that is, a collection of a series of intercepted methods.
e. Advice: refers to what to do after intercepting the connection point, that is, logical processing after intercepting. The usual permission verification, thing processing, logging and other operations are defined and completed in notifications.
f. Target: The target object of the proxy, that is, the intercepted object. As in the above example, the object where the method is located.
g. Weave: refers to the process of applying a section to the target object and causing the creation of a proxy object.
h. Introduction: Without modifying the code, the introduction can dynamically add some methods and fields to the class during the runtime.
4. Spring supports dependencies that support Oriented Programming (AOP):
The following 3 packages in the directory after Spring is decompressed:
lib/aspectj/aspectjweaver.jarlib/aspectj/aspectjrt.jarlib/cglib/cglib-nodep-2.1-3.jar
5. When using aspect-oriented programming (AOP) in spring, you need to introduce the aop namespace in the spring configuration file, that is, add the following configuration:
xmlns:aop=”http://www.springframework.org/schema/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: Spring 2.5 provides two AOP methods, namely, based on XML configuration file and Java annotation method.
To use annotation method AOP, you need to add the following object annotation method AOP support in the spring configuration file:
<aop:aspectj-autoProxy/>
6. JavaBean packaging class - BeanWrapper:
Spring encapsulates the behavior of a javabean through the BeanWrapper class, and can set and obtain its attribute values, such as:
BeanWrapper wrapper class object = BeanWrapperImpl(new wrapped class()); wrapper class object.setPropertyValue("property name", "property value");
This method allows you to set properties to the wrapped class.
7. Oriented-oriented programming (AOP) development based on annotation:
(1). Add AOP support for annotation methods in the spring configuration file.
(2). Define the section:
Similar to creating a normal class, adding the "@Aspect" annotation before the class indicates that the class is a section.
(3). Add entry points to the cut surface:
A point-cutting point is a collection of intercepted objects methods. Usually, the point-cutting point is defined in a method of processing the point-cutting point in the section. Use the "@Pointcut" annotation, and the syntax is as follows:
@Pointcut("execution(* com.test.service..*.*(..))") public void anyMethod(){//The method is called "point-cut" and "point-cut" processing}
Detailed explanation of syntax parameters:
a. The first "*": means that the method being intercepted is an arbitrary return type.
b. com.test.service: Here is a simple example, indicating the name of the package to be intercepted, that is, the packet to be intercepted.
c. The two ".." after the intercepted packet name: means that the subpackets below the intercepted packet are also intercepted recursively, that is, the intercepted subpacket.
d. "*" after "..": represents all classes below the intercepted packet and its subpackage, that is, the intercepted class.
e. The last "*": represents all methods in the intercepted class, that is, the intercepted method.
f. "(..)": means that the intercepted method receives any parameters, that is, the intercepted parameters.
Note: Point-cut definition syntax can support wildcard characters, but you must strictly follow the syntax rules. like:
@Pointcut("execution(*com.test.service..*.add*(..))") It means intercepting methods starting with "add" in all classes under the com.test.service package and its subpackage.
(4). Add notifications to the section:
For notification locations in Spring, please refer to the small examples in 3.
"@Before" annotation: declare a pre-notification.
"@AfterRutruning" annotation: declare post-notification.
"@After" annotation: Declare the final notice.
"@AfterThrowing" annotation: declare exception notification.
"@Around" annotation: declares surrounding notifications.
An example of defining notifications is as follows:
@Before("anyMethod()(the entry point name declared in the slit face)") public void doAccessCheck(){ ... }
Note: The surround notification is slightly different from the other 4 types of notifications. The definition of surround notification is more special. The surround notification will work before and after the entire method call, so the connection point object must be used to tell the connection point to continue its logical processing after the surround notification processing. Its definition is as follows:
@Around(Search into point name) public Object doBasicProfiling(ProcedingJoinPoint pjp) throws Throwable{ ... return pjp.proceed();//This sentence tells the connection point to continue to perform other operations} 8. Some tips for development of aspect-oriented programming (AOP) based on annotation:
(1). Get input parameters:
like:
@Before("Sign up the dot name && args(input parameter name)") public void doSomething(String input parameter name){...}
(2). Get the return result:
like:
@AfterReturning(Pointcut=”Sign in point name”, return=”Return result name”) public void dosomething(String result name){…}
9. Development of section-oriented programming (AOP) based on XML:
(1). Define the facet class and add notifications to the facet class.
(2). Configure the facet class in the spring configuration file like the ordinary java class.
(3). Add AOP configuration in the spring configuration file as follows:
<aop:config> <!--Configuration Section--> <aop:aspect id="Section ID" ref="id of the section class in the spring configuration file"> <!--Configuration Point--> <aop:pointcut id="Section ID" expression="execution(* com.test.service..*.*(..))"/> <!--Configuration Notification--> <aop:before pointcut-ref="Section id" method="Responsible processing methods in the section class"/> <aop:after …/> … </aop:aspect> </aop:config>
10. Spring's transaction processing (Spring's declarative transaction processing):
Simply put, a transaction refers to one of the most basic operations in the database. A detailed explanation of the transaction will be explained in detail in the database related summary. One of the most important applications of Spring's Oriented Oriented Programming (AOP) is transaction management. The transaction management of Spring 2.5 and later versions support two types of annotation-based methods and XML files-based methods:
(1). Transaction management based on annotation method:
a. Add transaction management namespace in the spring configuration file as follows:
xmlns:ts=http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
b. Configure the transaction manager in the spring configuration file as follows:
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”id of the data source bean configured in spring”/>
c. Add transaction configuration items that support annotation methods in the spring configuration file are as follows:
<tx:annotation-driventransaction-manager-tx:annotation-driventransaction-manager=”txManager(id of transaction manager bean configured in spring)”/>
d. Use annotation-based transaction management:
In the JavaEE project managed by Spring, the business logic of the transaction needs to be added with the "@Transactional" annotation.
(2). Transaction management based on XML file method:
a. Configure the transaction manager in the spring configuration file as follows:
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”id of the data source bean configured in spring”/>
b. Add the following sections of thing management in the spring configuration file:
<aop:config> <!--Configure transaction entry point--> <aop:pointcut id=”transactionPointcut” Expression=”execution(* com.test.service..*.*(..))”/> <!--Configure transaction notification--> <aop:advisor advice-ref=”txAdvice” pointcut-ref=”transactionPointcut”/> </aop:config>c. Add the following features for transaction notifications in the spring configuration file:
<tx:advice id=”txAdvice” transactionManager=”txManager”> <tx:attributes> <!-- Here is an example to set the query method starting with get to read-only, and does not support transactions --> <tx:method name=”get*” read-only=”true” propagation=”NOT_SUPPORTED”/> <!--Other methods are set to spring's default thing behavior--> <tx:method name=”*”/> </tx:attributes> </tx:advice>