AOP is called aspect-oriented programming, which is mainly used in program development to solve some system-level problems, such as log, transaction, permission Wait, Struts2 Interceptor design is based on the idea of AOP, is a more classic example.
A basic concept of AOP
(1) Aspect (tangent): Usually a class in which you can define pointcuts and notifications
(2) Jointpoint (connection point): A definite point in the execution of a program, usually a call to a method
(3) Advice (Notification): The enhanced processing that AOP performs on a particular pointcut, with Before,after,afterreturning,afterthrowing,around
(4) Pointcut (entry point): Is the connection point with the notification, in the program is mainly embodied in the writing pointcut expression
(5) AOP Proxy: An object created by the AOP framework, the proxy is the enhancement of the target object. The AOP proxy in spring can either make the JDK dynamic proxy or the Cglib proxy, which is based on the interface, which is based on the subclass
Two Spring AOP
The AOP agent in spring is still inseparable from the spring IOC container, the generation of proxies, the management and their dependencies are the responsibility of the IOC container, and spring uses the JDK dynamic proxy by default, when the proxy class is needed instead of the proxy interface. Spring automatically switches to using the Cglib proxy, but now the project is programming interface-oriented, so the JDK dynamic agent is relatively more.
Three annotations-based approach to AOP configuration
1. Enable @asjectj support
In Applicationcontext.xml, configure the following sentence:
<aop:aspectj-autoproxy/>
2. Description of the notification type
(1) Before: For enhanced processing before the target method is called, @Before only need to specify the pointcut expression to
(2) Afterreturning: After normal completion of the target method is enhanced, @AfterReturning in addition to specifying a pointcut expression, you can also specify a return value parameter name returning, which represents the return value of the target method
(3) Afterthrowing: Used primarily to handle unhandled exceptions in a program, @AfterThrowing you can specify a throwing return value parameter name in addition to the pointcut expression, which can be specified by the parameter name
To access the exception object thrown in the target method
(4) After: Does the enhancement after the target method is complete, regardless of the target method when it is completed successfully. @After can specify a pointcut expression
(5) Around: Surround notification, before and after the target method is done to enhance processing, surround notification is the most important notification type, such as transactions, logs, etc. are surrounded by notifications, note that the core of programming is a proceedingjoinpoint
3. Example:
(1) Operator.java--Plane class
@Component @aspectPublicClassOperator {@Pointcut ("Execution (* com.aijava.springcode.service). *.*(..))")PublicvoidPointCut () {} @Before ("PointCut ()")PublicvoidDobefore (Joinpoint joinpoint) {System.out.println ("AOP before Advice ..."); } @After ("PointCut ()")PublicvoidDoafter (Joinpoint joinpoint) {System.out.println ("AOP after Advice ..."); } @AfterReturning (pointcut= "pointcut ()", returning= "ReturnVal")PublicvoidAfterreturn (Joinpoint joinpoint,object returnval) {System.out.println ("AOP afterreturning Advice:" +ReturnVal); } @AfterThrowing (pointcut= "pointcut ()", throwing= "error") public void afterthrowing (joinpoint joinpoint,throwable error) {System.out.println (" AOP afterthrowing Advice ... ") + error); System.out.println ("afterthrowing ..." ) public void around (Proceedingjoinpoint PJP) { System.out.println ("AOP aronud before ..." try {pjp.proceed ();} catch (Throwable e) {e.printstacktrace ();} System.out.println ("AOP aronud after ..."
(2) Userservice.java--Define some target methods
@Servicepublic class UserService { public void add () { System.out.println ("UserService Add ()" public boolean Delete () { System.out.println ("UserService Delete ()" return truepublic void edit () {System.out.println ( "UserService edit ()" ); int i = 5/0;}}
(3). Applicationcontext.xml
<Base-package= "Com.aijava.springcode"/> </>
(4). Test.java
Class Test { voidnew Classpathxmlapplicationcontext ("Classpath:applicationContext.xml"); UserService UserService = (userservice) ctx.getbean ("UserService"); Userservice.add ();}}
The above is a relatively simple test that basically covers a variety of enhancement definitions. Note: When you do a surround notification, calling Proceedingjoinpoint's proceed () method executes the target method.
4. Priority of notification execution
Enter the target method, first weaving into the around, and then weaving into the before, exit the target method, first weaving into the around, and then weaving into the afterreturning, and finally weaving into after.
Note: Spring AOP surround notifications can affect the operation of afterthrowing notifications and do not use them at the same time! It doesn't make sense to use it at the same time.
5. Definition and expression of pointcuts
The definition of pointcut expression is the core of the whole AOP, a set of its own specifications
Pointcut indicators supported by Spring AOP:
(1) Execution: The connection point used to match the execution method
A: @Pointcut ("Execution (* com.aijava.springcode.service). *.*(..))")
The first * means matching any of the method return values: (Two dots) represents 0 or more, the first of the above: Represents a service package and its child packages, the second * represents all classes, the third represents all methods, and the second: Said
Any number of arguments to the method
B: @Pointcut ("Within (com.aijava.springcode.service.*)")
Within the connection point of the qualifying match method, which represents any connection point under the matching service package
C: @Pointcut ("This (Com.aijava.springcode.service.UserService)")
This is used to qualify an AOP proxy to be an instance of a specified type, as above, specifying a specific instance, which is UserService
D: @Pointcut ("Bean (UserService)")
Beans are also very common, and beans can specify the name of the bean in the IOC container
6. The configuration method based on XML form
In the development of the use of XML configuration, usually is pojo+xml to develop AOP, very similar, is nothing more than write pointcut expressions and notification types in the XML file
Example:
(1) Log.java
PublicClassLog {PrivateInteger ID;//Action Name, method namePrivateString Opername;// operator private String operator; // operating parameters private String operparams; // operation result succeeded/failed private String Operresult; // result message private String resultmsg; // operating time private Date opertime = new date (); Setter,getter}
(2). Logger.java
/*** Logger (AOP log notification)*/PublicClassLogger {@ResourcePrivateLogservice Logservice;PublicObject record (Proceedingjoinpoint pjp) {log log =NewLog ();Try{log.setoperator ("admin"); String Mname =Pjp.getsignature (). GetName (); Log.setopername (Mname);//Method parameter, in this case user user object[] args =Pjp.getargs (); Log.setoperparams (arrays.tostring (args));//Executes the target method, returning the return value of the target method, in this case void Object obj =Pjp.proceed ();if (obj! =null) {log.setresultmsg (obj.tostring ());} else{log.setresultmsg ( Nullnew< Span style= "COLOR: #000000" > Date ()); return obj;} catch (Throwable e) {log.setoperresult ("failure" finally{logservice.savelog (log);} return null;}}
(3). Applicationcontext.xml
<Aop:config><Aop:aspectid= "Loggeraspect" ref< Span style= "COLOR: #0000ff" >= "logger" > <aop:around method= "Record" Pointcut= "(Execution (* com.aijava.distributed.ssh.service). *.add* (..)) or Execution (* com.aijava.distributed.ssh.service). *.update* (..)) or Execution (* com.aijava.distributed.ssh.service). *.delete* (..))) and!bean (logservice) "/> </ aop:aspect></< Span style= "COLOR: #800000" >aop:config>
Note the pointcut expression,!bean (logservice) Do log notification, do not log the log itself, otherwise it will cause an infinite loop!
For more detailed spring AOP knowledge, you can view the spring Official document 9th chapter aspect oriented programming with spring
7.JDK Dynamic Agent Introduction
Example:
(1) Userservice.java
Interface UserService { void Add ();}
(2) Userserviceimpl.java
Implements userservice{ void Add () {System.out.println ("User Add () ...");}}
(3) Proxyutils.java
PublicClass ProxyutilsImplementsinvocationhandler{PrivateObject Target;PublicProxyutils (Object target) {This.target = target;} public Object Gettarget () { return target;} public void Settarget ( Object target) {this.target = target;} public object Invoke (Object proxy, Method method, object[] args) throws Throwable {System.out.println ("Do sth before ..." return null;}}
(4) Test.java
Class Test { voidnewnew proxyutils (UserService); UserService proxyobject = (userservice) proxy.newproxyinstance (Thread.CurrentThread (). GetContextClassLoader (), Userserviceimpl. class. Getinterfaces (), proxyutils); Proxyobject.add ();}}
JDK Dynamic Agent core is still a invocationhandler, remember this is OK.
Spring AOP Detailed Introduction