[Spring] AOP-based XML configuration summary and cases, springaopxml case
Original works of Lin bingwen Evankaka. Reprinted please indicate the source http://blog.csdn.net/evankaka
I. Some Concepts of AOP
AOP (Aspect-Oriented Programming) can be said to be a supplement and perfection of OOP (Object-Oriented Programing, object-oriented Programming. OOP introduces concepts such as encapsulation, inheritance, and Polymorphism to establish an object hierarchy to simulate a set of public behaviors. When we need to introduce public behavior to scattered objects, OOP seems powerless. That is to say, OOP allows you to define the relationship from top to bottom, but it is not suitable for defining the relationship from left to right. For example, log function. Log Code is often horizontally distributed across all object layers, but it has nothing to do with the core functions of the objects it spreads. This is also true for other types of code, such as security, exception handling, and transparent persistence. This unrelated code distributed everywhere is called cross-cutting code. in OOP design, it leads to a large number of code duplication, which is not conducive to the reuse of each module.
The AOP technology is the opposite. It uses a technology called "cross-cutting" to segment the encapsulated object, encapsulate the public behaviors that affect multiple classes into a reusable module and name it "Aspect", that is, the Aspect. The so-called "aspect" is simply to encapsulate the logic or responsibilities that are irrelevant to the business but are called by the business module to reduce repeated system code, reduce the coupling between modules and facilitate future operability and maintainability. AOP represents a horizontal relationship. If "object" is a hollow cylinder that encapsulates the attributes and behaviors of objects, then the method for Aspect-Oriented Programming, it is like a sharp blade that splits these hollow cylinders to obtain internal messages. The cut section is also called the cut section. Then it restored these cut sections with the skill of winning the power of heaven without leaving any trace.
Using the "cross-cutting" technology, AOP divides the software system into two parts: the core focus and the cross-cutting focus. The main process of business processing is the core focus, and the part that has little to do with it is the cross-cutting focus. One feature of cross-cutting concerns is that they often occur in multiple places of core concerns, and are similar everywhere. For example, permission authentication, logs, and transaction processing. The function of Aop is to separate the various concerns in the system from the core concerns and the cross-cutting concerns. As Adam Magee, Avanade's senior Solution Architect, said, the core idea of AOP is to "separate the business logic in applications from the general services it supports ."
The technology for Implementing AOP is mainly divided into two categories: one is to use dynamic proxy technology, and use the method of intercepting messages to describe the message to replace the execution of the original object behavior; the second is to use static weaving to introduce specific syntax to create "cut-plane", so that the compiler can weave the "cut-plane" code during compilation. However, the same way is achieved, and the technical features for Implementing AOP are the same:
1. join point: a precise execution point in program execution, such as a method in the class. It is an abstract concept. When Implementing AOP, you do not need to define a join point.
2. point cut: essentially a structure that captures the connection points. In AOP, you can define a point cut to capture calls to related methods.
3. advice (notification): indicates the Execution Code of the point cut and the specific logic for executing the "aspect.
4. aspect: the combination of point cut and advice is aspect. It is similar to a class defined in OOP, but it represents more of a horizontal relationship between objects.
5. introduce (Introduction): introduces additional methods or attributes to an object to modify the object structure. Some AOP tools call it mixin.
6. AOP Proxy: the object created by the AOP framework. This object can be used as a substitute for the target object. The AOP Proxy provides more powerful functions than the target object. The actual situation is that when the application calls the method of the AOP proxy, the AOP proxy calls back the method of the target object in its own method to complete the application call. A typical example of AOP proxy is the transaction proxy Bean in Spring. Generally, the method of the target Bean is not transactional, And the AOP proxy contains all the methods of the target Bean, and these methods have been enhanced into transactional methods. Simply put, the target object is the blueprint, and the AOP proxy is the enhancement of the target object. Based on the target object, attributes and methods are added to provide more powerful functions.
The target object contains a series of entry points. The starting point can trigger the processing of the collection of connection points. You can define the entry point by yourself, for example, using a regular expression. The AOP proxy wraps the target object and adds processing to the entry point. The processing added to the entry point makes the method of the target object more functional. By default, Spring uses JDK dynamic proxy to implement AOP proxy, which is mainly used for proxy interfaces. You can also use the CGLIB proxy. The proxy of the implementation class, not the interface. If the business object does not implement interfaces, CGLIB proxy is used by default. But interface-oriented programming is a good habit. do not apply to specific classes as much as possible. Therefore, a business object must implement one or more interfaces.
7. Target Object: an Object that contains a connection point, also known as a proxy Object.
8. Before advice: A notification executed Before a connection point. However, this notification cannot be executed Before a connection point. In ApplicationContext, use the <aop: before> element in <aop: aspect> for declaration.
9. After notification (After advice): The Notification executed when a connection point exits (whether it is a normal return or an abnormal exit ). In ApplicationContext, use the <aop: after> element in <aop: aspect> for declaration.
10. After return notification (After return advice): The Notification executed After a connection point is completed normally, excluding the exception thrown. In ApplicationContext, use the <after-returning> element in <aop: aspect> for declaration.
11. Surround notification (Around advice): notifications that enclose a connection point, similar to the doFilter method of the Filter in the Servlet specification in the Web. You can customize the behavior before and after the method is called, or you can choose not to execute. In ApplicationContext, use the <aop: around> element in <aop: aspect> for declaration.
12. notification After an exception is thrown (After throwing advice): Notification executed when the method throws an exception and exits. In ApplicationContext, use the <aop: after-throwing> element in <aop: aspect> for declaration.
Currently, Spring2.0 only supports using method calls as the join point ).
Spring defines the entry point Syntax: excution (modifiers-pattern? Ret-type-pattern declaring-type-pattern? Name-pattern (param-pattern) throws-pattern ?)
Except ret-type-pattern (return type mode) and name-pattern (param-pattern), other modes are optional. The return type mode determines that the return type of a method must match a connection point (that is, a method) in sequence ). The most frequently used return type mode is *, which indicates matching any return type. If you specify the return type, such as String, only the connection points (methods) of the String type can be returned ). The name pattern matches the method name. You can use the * wildcard to match all method names. In parameter mode, () indicates that the method that does not accept any parameters is matched, and (..) The method that matches any number of parameters. Mode (*) indicates a method that matches any type of parameters. Mode (*, String) indicates matching: the first is of any parameter type, and the second must be of the String type.
2. configuration of AOP Based on Schema (XML)
From Spring2.0 and later, AOP uses the "aop" namespace to define cut points, entry points, and Declaration notifications.
In the Spring configuration file, the relevant AOP definitions must be placed under the <aop: config> label, which can include <aop: pointcut>, <aop: advisor>, <aop: aspect> label. The configuration sequence is unchangeable.
- <Aop: pointcut>: used to define the entry point, which can be reused;
- <Aop: advisor>: defines the aspect of a notification and an entry point;
- <Aop: aspect>: defines a plane. This plane can contain multiple entry points and notifications, and the notifications and entry point definitions in the label are unordered. The difference between the plane and the advisor is as follows, advisor only contains one notification and one entry point.
Declarative aspect
A section is an object that contains the entry point and notification. It is defined as a Bean in the Spring container. An xml section requires a section to support beans, the Bean fields and methods provide the status and behavior information of the slice, and specify the entry point and notification implementation through configuration.
The section is specified using the <aop: aspect> label, and the ref attribute is used to reference the Section to support Bean.
Declaration entry point
The entry point is also a Bean in Spring. Bean can be defined in three ways:
● Use <aop: pointcut> under the <aop: config> label to declare an entry point Bean. This entry point can be used by multiple sections. It is best to use this method for the entry points that need to be shared, this entry point uses the id attribute to specify the Bean name, and uses the pointcut-ref attribute to reference the entry point through this id during notification definition. The expression attribute specifies the entry point expression.
● Use the <aop: pointcut> label under the <aop: aspect> label to declare an entry point Bean. This entry point can be used by multiple sections, but generally this entry point is only used by this section, of course, it can also be used by other sections, but it is best not to use that method. This entry point uses the id attribute to specify the Bean name and uses the pointcut-ref attribute to reference the entry point through this id during notification definition, expression attribute specifies the entry point expression
● The anonymous entry point Bean can specify the entry point expression through the pointcut attribute when declaring a notification. This entry point is an anonymous entry point and is only used by this notification.
<aop:config> <aop:aspect ref="aspectSupportBean"> <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterAdvice"/> </aop:aspect> </aop:config>
Notification Declaration: (pre-notification, post-notification, and surround notification)
1. pre-notification:The notification that is executed before the method at the connection point selected by the start point does not affect the normal Program Execution Process (unless the notification throws an exception, this exception will interrupt the execution of the current method chain and return ).
In Spring, the execution is performed before the method selected by the starting point. The <aop: before> label declaration under the <aop: aspect> label is used:
<Aop: before pointcut = "pointcut expression" (or pointcut-ref = "pointcut Bean reference ") method = "Implementation method of pre-notification" arg-names = "Implementation method of pre-notification parameter list parameter name"/>
● Pointcut and pointcut-ref: select either of them and specify the start point;
● Method: Specifies the name of the pre-notification implementation method. If it is a polymorphism, the parameter type must be added. Multiple parameters are separated by commas (,), for example, beforeAdvice (java. lang. String );
● Arg-names: Specifies the parameter names of the notification implementation method. Multiple parameters are separated by commas (,). (optional) args (param) is used in the entry point) the matching target method parameters are automatically passed to the same name parameter of the notification implementation method.
2. Post-notification:Notifications executed after the method at the connection point selected by the start point include the following types of post notifications:
● Post-return notification: this notification is executed when the method at the connection point selected by the start point is normally executed. It must be called only when the method at the connection point does not throw any exceptions and returns normally.
Run the following command when the method selected by the start point returns normally: Use the <aop: after-returning> label declaration under the <aop: aspect> label:
<Aop: after-returning pointcut = "expression" pointcut-ref =" Bean reference" method = "arg" arg-names =" parameter list parameter Name "returning =" parameter name of the post-return notification implementation method corresponding to the returned value "/>
3. Post-exception notification:The notification is executed when the method at the connection point selected by the start point throws an exception and returns the exception. The exception notification is called only when the method at the connection point throws any exception and returns the exception.
Run the following command when an exception is thrown in the method selected by the start point: <aop: after-throwing> label declaration under the <aop: aspect> label:
<Aop: after-throwing pointcut = "expression" pointcut-ref =" Bean reference" method = "" arg-names = "parameter list parameter Name "throwing =" Name of the notification implementation method parameter assigned to the thrown exception "/>
4. Post-final notification:The notification that is executed when the method returned at the connection point selected by the start point is executed, regardless of whether an exception is thrown or not, similar to the finally block in Java.
Execute when the method selected by the start point is returned, whether it is a normal return or an exception thrown, and use the <aop: after> label declaration under the <aop: aspect> label:
<Aop: after pointcut = "expression" pointcut-ref =" Bean reference" method = "post-end notification implementation method name" arg-names = "post-end notification implementation method parameter list parameter name "/>
5. Surround notification:Notifications that are executed by the method at the connection point selected by the start point can be customized before and after the method call, it also determines whether to execute the method at the connection point, replace the return value, and throw an exception.
The notifications surround the methods executed at the connection points selected by the starting point. The notifications are very powerful and can determine whether the target method is executed, when it is executed, and whether the method parameters need to be replaced during execution, whether to replace the return value after the execution is complete. You can use the <aop: around> label declaration under the <aop: aspect> label:
<Aop: around pointcut = "expression" pointcut-ref =" Bean reference" method = "post-end notification implementation method name" arg-names = "post-end notification implementation method parameter list parameter name "/>
The first parameter of the surround notification must be org. aspectj. lang. proceedingJoinPoint type. In the notification implementation method, use the proceed () method of ProceedingJoinPoint to execute the target method. The proceed method can input an optional Object [] array, the value of this array will be used as the parameter for executing the target method.
Introduction
Spring allows you to introduce new interfaces to the target object by using the <aop: declare-parents> label in the <aop: aspect> label. The definition is as follows:
<Aop: declare-parents types-matching = "AspectJ syntax type expression" implement-interface = introduced interface "default-impl =" default Implementation of introduced interface "delegate-ref =" introduced interface bean reference by default "/>
Advisor
Advisor indicates that there is only one notification and one starting point. Because Spring AOP is based on the AOP interceptor model, therefore, Advisor is introduced to support various notification types (such as pre-notifications). The concept of Advisor comes from Spring1.2's support for AOP, and there is no corresponding concept in AspectJ.
The <aop: Advisor> label defined under the <aop: config> label can be used as follows:
<Aop: advisor pointcut = "expression" pointcut-ref =" Bean bean reference" advice-ref = "Notification API implementation reference"/> <Bean id = "beforeAdvice" class = "cn. javass. spring. chapter6.aop. beforeAdviceImpl "/> <aop: advisor pointcut =" execution (* cn. javass .. *. sayAdvisorBefore (..)) "advice-ref =" beforeAdvice "/>
Iii. Examples
Be sure to import these packages!
Aspectjweaver. jar
Aopalliance-1.0.jar
1. Human Interface Class
Package com. mucfc;/*** function Person interface class * Author Lin bingwen (ling20081005@126.com blog: http://blog.csdn.net/evankaka) * time 2015.4.24 */public interface Person {public void eatBreakfast (); public void eatLunch (); public void eatSupper ();}
2. Baby implementation class
Package com. mucfc;/*** implementation class * Author Lin bingwen (ling20081005@126.com blog: http://blog.csdn.net/evankaka) * time 2015.4.24 */public class BabyPerson implements Person {@ Overridepublic void eatBreakfast () {System. out. println ("little Baby is eating breakfast") ;}@ Overridepublic void eatLunch () {System. out. println ("Baby is eating lunch") ;}@ Overridepublic void eatSupper () {System. out. println ("little Baby is eating dinner ");}}
3. Write the methods to be enhanced in a file.
Package com. mucfc; import org. aspectj. lang. ProceedingJoinPoint; public class AdivceMethod {public void beforeEat () {System. out. println ("------------------- wash your hands before eating! -------------------- ");} Public void afterEat () {System. out. println (" ------------------- take a nap after lunch! -------------------- ");} Public Object aroundEat (ProceedingJoinPoint pjp) throws Throwable {System. out. println (" ----------------- have fun before dinner! ------------------- "); Object retVal = pjp. proceed (); System. out. println (" ------------------- it's time to go to bed after dinner! ------------------- "); Return retVal ;}}
4. Here is the focus. Use aop: config directly.
<? Xml version = "1.0" encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <Bean id = "babyPerson" class = "com. mucfc. BabyPerson"/> <! -- Enhanced bean --> <bean id = "adviceAspect" class = "com. mucfc. AdivceMethod"/> <! -- Enhancement Method bean --> <aop: config proxy-target-class = "true"> <aop: pointcut id = "pointcut" expression = "execution (* com. mucfc. babyPerson. *(..)) "/> <! -- Define the cut point --> <aop: aspect ref = "adviceAspect"> <! -- Define a cut --> <aop: before method = "beforeEat" pointcut-ref = "pointcut"/> <! -- Define the pre-enhancement method --> <aop: after method = "afterEat" pointcut = "execution (* com. mucfc. BabyPerson. eatLunch (..)"/> <! -- Add after definition, use anonymous cut point --> <aop: Und und method = "aroundEat" pointcut = "execution (* com. mucfc. babyPerson. eatSupper (..)) "/> <! -- Add after definition and use anonymous cut points --> </aop: aspect> </aop: config> </beans>
5. Test
package com.mucfc;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml"); Person babyPerson=(BabyPerson)context.getBean("babyPerson"); babyPerson.eatBreakfast(); babyPerson.eatLunch(); babyPerson.eatSupper(); }}
Result:
The XML-based configuration method is easier to implement than the API-based method described above, and the code looks easier to solve. I have to admire the power of Spring!
Original works of Lin bingwen Evankaka. Reprinted please indicate the source http://blog.csdn.net/evankaka