AOP is commonly implemented in two ways, one implemented declaratively (based on XML) and one implemented in annotations (based on ASPECTJ).
First review some of the more important concepts in AOP:
Joinpoint (connection point): a particular point in the execution of a program, which is the execution of a method in spring.
Pointcut (tangent): Speaking of popular points, the tangent point of AOP in spring refers to a collection of methods that need to be enhanced and proxied. are generally expressed in accordance with certain rules, such as regular expressions. Tangency is made up of a class of connection points.
Advice (notice): or the popular point, is to specify what to do on the pointcut.
Advisor (notifier): is actually a combination of pointcuts and notifications.
One, XML-based configuration of spring AOP
Implemented declaratively (configured in an XML file), the approximate step is to configure Pointcut in the configuration file and write the actual aspect class in Java for business processing of the pointcut.
Business interface:
Package Com.spring.service;public interface Iusermanagerservice { //Find User public String finduser (); Add user public void AddUser ();}
Business implementation:
Package Com.spring.service.impl;import Com.spring.service.iusermanagerservice;public Class UserManagerServiceImpl Implements iusermanagerservice{ private String name; public void SetName (String name) { this.name=name; } Public String GetName () { return this.name; } Public String Finduser () { System.out.println ("============ executes the business method Finduser, the lookup user is:" +name+ "============="); return name; public void AddUser () { System.out.println ("============ Execution of Business method adduser============="); throw new RuntimeException ();} }
Slice class:
Package Com.spring.aop;import Org.aspectj.lang.joinpoint;import Org.aspectj.lang.proceedingjoinpoint;public class Aopaspect {/** * pre-notification: code executed before the target method call * @param JP */public void Dobefore (Joinpoint jp) {Syst EM.OUT.PRINTLN ("=========== implementation of the pre-notification ============"); /** * back-to-back notification: code executed after the target method normally ends * Return notification is a return value that can access the target method * @param JP * @param result */public void doafterreturning (Joinpoint jp,string result) {System.out.println ("=========== performs post-notification ============"); System.out.println ("Return value result===================" +result); /** * Final notification: Code executed after the target method call (regardless of whether the target method has an exception) * The return value of the method cannot be returned because the method may have an exception * @param JP */Public V OID Doafter (joinpoint JP) {System.out.println ("=========== performs final notification ============"); }/** * Exception notification: The code executed when the target method throws an exception can access the exception object * @param JP * @param ex */public void Doaf Terthrowing (Joinpoint jp,exception ex) {System.out.println ("========== = Execute exception notification ============ "); /** * Surround notification: Code executed before and after the target method call can complete the custom behavior before and after the method call. * A notification that surrounds a connection point. It executes the corresponding section before the Pointcut method executes and the method ends. * Mainly call the proceed () method to execute the Pointcut method as a watershed for the method before and after the notification. * Surround notification is similar to the whole process of dynamic agents: Parameters of the Proceedingjoinpoint type can determine whether to execute the target method. * and the surround notification must have a return value, which is the return value of the target method * @param PJP * @return * @throws throwable */Public Object Doaround (Proc Eedingjoinpoint pjp) throws throwable{System.out.println ("====== performs surround notification start ========="); parameter of the calling method object[] args = Pjp.getargs (); The method name of the call is String methods = Pjp.getsignature (). GetName (); Gets the target objects object target = Pjp.gettarget (); Executes the return value of the method//calls the proceed () method, which triggers the Pointcut method to execute Object result=pjp.proceed (); System.out.println ("Output, Method Name:" + methods + "; target object:" + target + "; return value:" + result); System.out.println ("====== performs surround notification end ========="); return result; }}
Spring Configuration:
<?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" xmlns:p= " http://www.springframework.org/schema/p "xsi:schemalocation=" Http://www.springframework.org/schema/beans/http Www.springframework.org/schema/beans/spring-beans-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX/HTTP Www.springframework.org/schema/tx/spring-tx-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP/HTTP Www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--Declare a business class--<bean id=" Usermanager "Clas s= "Com.spring.service.impl.UserManagerServiceImpl" > <property name= "name" value= "Lixiaoxi" ></property > </bean> <!--Notice class-<bean id= "Aspectbean" class= "Com.spring.aop.AopAspect"/> <aop:config> <aop:aspect ref= "Aspectbean" > <aop:pointcut id= "pointcut" expression= "Execution (* Com.spring.service.impl.UserManagerServiceImpl). *(..))" /> <aop:before method= "Dobefore" pointcut-ref= "Pointcut"/> <aop:after-returning method= "Doafterreturning" pointcut-ref= "pointcut" returning= "result"/> <aop:after method= "doafter" pointcut-ref= "poi Ntcut "/> <aop:around method=" Doaround "pointcut-ref=" Pointcut "/> <aop:after-throwing method=" Doafterthrowing "pointcut-ref=" Pointcut "throwing=" ex "/> </aop:aspect> </aop:config></beans>
Test class:
Package Com.spring.test;import Org.springframework.context.applicationcontext;import Org.springframework.context.support.classpathxmlapplicationcontext;import Com.spring.service.iusermanagerservice;public class Testaop {public static void Main (string[] args) throws exception{ ApplicationContext act = New Classpathxmlapplicationcontext ("Applicationcontext3.xml"); Iusermanagerservice Usermanager = (iusermanagerservice) act.getbean ("Usermanager"); Usermanager.finduser (); System.out.println ("\ n"); Usermanager.adduser (); }}
Test results:
Ii. Configuring AOP with annotations
Using annotations to do AOP, the main thing is to write the connection points written in the spring configuration file into the annotations.
Business interfaces and business implementations as above, the specific slice class is as follows:
Package Com.spring.aop;import Org.aspectj.lang.joinpoint;import Org.aspectj.lang.proceedingjoinpoint;import Org.aspectj.lang.annotation.after;import Org.aspectj.lang.annotation.afterreturning;import Org.aspectj.lang.annotation.afterthrowing;import Org.aspectj.lang.annotation.around;import Org.aspectj.lang.annotation.aspect;import Org.aspectj.lang.annotation.Before; @Aspectpublic class Aopaspectj {/** * Must be a final string type, the variable to be used in the note can only be a static constant type of */public static final String edp= "Execution (* com.spring.service . Impl. Usermanagerserviceimpl. *(..))"; /** * The front-end method of the tangent plane is the method that is intercepted before the method executes * notification before the target method is executed * @param JP */@Before (EDP) public void Dobefore (Joinpoi NT JP) {System.out.println ("========= performs pre-notification =========="); /** * Notifications executed after the normal execution of the method are called return notifications * can be returned to the return value of the method after the annotation is added returning * @param JP * @param result */@AfterReturning (value=edp,returning= "result") public void doafterreturning (Joinpoint jp,string result) {System.out.println ("=========== performs post-notification ============"); /** * Final notification: Notification executed after the target method call (regardless of the target method execution) * @param JP */@After (VALUE=EDP) public void Doafter (Joinpoint JP) {System.out.println ("=========== performs final Notice ============"); /** * Surround Notification: A notification that is executed before and after a target method call can complete the custom behavior before or after the method call. * @param PJP * @return * @throws throwable * * @Around (EDP) public Object doaround (Proceedingjoinpoint PJ p) throws throwable{System.out.println ("====== execution surround notification start ========="); parameter of the calling method object[] args = Pjp.getargs (); The method name of the call is String methods = Pjp.getsignature (). GetName (); Gets the target objects object target = Pjp.gettarget (); Executes the return value of the method//calls the proceed () method, which triggers the Pointcut method to execute Object result=pjp.proceed (); System.out.println ("Output, Method Name:" + methods + "; target object:" + target + "; return value:" + result); System.out.println ("====== performs surround notification end ========="); return result; }/** * In Target method non-Normal execution completes, throws an exception when will go this way * @param JP * @param ex */@AfterThrowing (value=edp,throwing= "ex") public void DoA Fterthrowing (Joinpoint jp,exception ex) {System.out.println ("=========== to perform exception notification ============"); }}
Spring Configuration:
<?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" xmlns:p= " http://www.springframework.org/schema/p "xsi:schemalocation=" Http://www.springframework.org/schema/beans/http Www.springframework.org/schema/beans/spring-beans-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX/HTTP Www.springframework.org/schema/tx/spring-tx-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP/HTTP Www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--declares spring's support for @aspectj--<aop:aspectj-a Utoproxy/> <!--declaring a business class--<bean id= "Usermanager" class= "Com.spring.service.impl.UserManagerSer Viceimpl "> <property name=" name "value=" Lixiaoxi "></property> </bean> <!--declaration Notification class--<bean id= "Aspectbean" class= "Com.spring.aoP.AOPASPECTJ "/></beans>
Test class:
Package Com.spring.test;import Org.springframework.context.applicationcontext;import Org.springframework.context.support.classpathxmlapplicationcontext;import Com.spring.service.iusermanagerservice;public class TestAop1 {public static void Main (string[] args) throws exception{ ApplicationContext act = New Classpathxmlapplicationcontext ("Applicationcontext4.xml"); Iusermanagerservice Usermanager = (iusermanagerservice) act.getbean ("Usermanager"); Usermanager.finduser (); System.out.println ("\ n"); Usermanager.adduser (); }}
The test results are the same as above.
Attention:
1. Surround method notification, surround method notification to be aware that the return value must be given after the call, otherwise the proxy method stops the call and returns NULL unless you really intend to do so.
2. Only surround notifications can use Joinpoint's subclass Proceedingjoinpoint, and each connection point type can invoke the proxy's method and get and change the return value.
Add:
1.<aop:pointcut> if it is in the <aop:aspect> element, the named Pointcut can only be accessed by the elements defined in the current <aop:aspect>, in order to be able to be the entire <aop:config> element, you must define a pointcut under <aop:config>.
2. If you define <AOP:POINTCUT> directly under the <aop:config> element, you must ensure that <aop:pointcut> is defined before <aop:aspect>. <aop:advisor> can also be defined under <aop:config>, and the configuration of the three in <aop:config> is ordered in order: the first must be <aop:pointcut> <aop:advisor>, and finally the <aop:aspect>. The <aop:pointcut> defined in <aop:aspect> has no sequencing requirements and can be defined in any location.
. <aop:pointcut>: Used to define the pointcut, the pointcut can be reused;
. <aop:advisor>: Used to define a facet with only one notification and one pointcut;
. <aop:aspect>: Used to define a slice that can contain multiple pointcuts and notifications, and that the notification and pointcut definitions inside the label are unordered; The advisor differs from this, and advisors only contain one notification and one pointcut.
3. When using the spring framework to configure AOP, you need to define Pointcut "pointcuts" either through XML configuration files or annotations.
For example, define pointcut expression Execution (* Com.sample.service.impl: *.*(..))
Execution () is the most commonly used pointcut function, and its syntax is as follows:
The entire expression can be divided into five parts:
(1), Execution (): The body of an expression.
(2), the first * Number: Indicates the return type, the * number denotes all types.
(3), package name: Indicates the package name that needs to be intercepted, and the following two periods represent all of the current package and all the child packages of the current package, Com.sample.service.impl the package, the descendants of all classes under the method.
(4), second * Number: Indicates the class name, * indicates all classes.
(5), * (..): The last asterisk denotes the method name, the * number denotes all methods, the arguments in parentheses indicate the parameters of the method, and two periods represent any parameters.
Two ways to implement the AOP implementation of the Spring series