1, AOP introduction
1. Basic concept of AOP
AOP is the abbreviation of Aspect Oriented Programming, which means: it is a technology to realize the unified maintenance of program functions through precompile mode and dynamic agent during operation. AOP is the continuation of OOP (object-oriented programming), a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can be used to isolate all parts of the business logic, which reduces the coupling between the parts of the business logic, improves the reusability of the program, and improves the efficiency of development.
2. AOP vs. OOP
Although AOP and OOP are very similar in literal terms, they are two design ideas for different fields. OOP (object-oriented programming) encapsulates the entities and their attributes and behaviors of business processes in an abstract way, so as to achieve a clearer and more efficient division of logical units. AOP is to extract the facets in the process of business processing. It is faced with a certain step or stage in the process to obtain the isolation effect of low coupling between the parts in the logic process. There are essential differences between the two design ideas in objectives.
3. My understanding of AOP is as follows:
We extract and encapsulate the common behaviors of all objects. For a
2, spring AOP
1, Basic concepts of spring AOP
1. Aspect: usually a class, in which pointcuts and notifications can be defined
2. Jointpoint: a specific point in the execution of a program, usually a method call
3. Advice: the enhanced processing performed by AOP at a specific entry point,
Before, after, after returning, after throwing, around
4. Pointcut: it is the connection point with notification, which is mainly embodied in writing the pointcut expression in the program
5.AOP proxy: the object created by the AOP framework. Proxy is the enhancement of the target object. AOP proxy in Spring can make JDK dynamic proxy or CGLIB proxy. The former is based on interface and the latter is based on subclass
II. Spring AOP
the AOP agent in Spring is still inseparable from the Spring IOC container. The generation, management and dependency of the agent are all in the charge of the IOC container. By default, Spring uses the JDK dynamic agent. When it needs the proxy class instead of the proxy interface, Spring will automatically switch to the CGLIB agent. However, the current projects are all interface oriented programming, so the JDK dynamic agent is relatively used More. The following is the spring aop configuration:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd " > <!-- Put the classes that need to be enhanced spring container --> <bean name="ps" class="com.wang.service.impl.ProductService"></bean> <!-- Put the enhanced class spring container --> <bean name="myAdvice1" class="com.wang.test4.MyAdvice1"></bean> <!-- To configure AOP --> <aop:config> <!-- breakthrough point --> <aop:pointcut id="pc1" expression="execution(public void com.wang.service.impl.ProductService.save())" /> <!-- Tangent (to cut the enhanced code into the target) --> <aop:aspect ref="myAdvice1"> <!-- Weaving pre reinforcement --> <aop:before pointcut-ref="pc1" method="open" /> </aop:aspect> </aop:config> </beans>
package com.wang.service.impl; import org.springframework.stereotype.Component; import com.wang.service.IProductService; /** * Implementation class of goods. * * Add, delete, change, check! * */ //@Component / / put the commodity implementation class into the container public class ProductService implements IProductService{ @Override public void save() { // System.out.println("open transaction"); System.out.println("save()"); // System.out.println("commit transaction"); // Simulated abnormality // int i = 1/0; }
package com.wang.test4; import org.aspectj.lang.ProceedingJoinPoint; /** * Notification class. * */ public class MyAdvice1 { /* * This is an enhanced class. * Put this class in the spring container! */ public void open() { System.out.println("Open transaction!"); } public void close() { System.out.println("Closing transaction!"); } }
Configuration enhanced to all types
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <!-- Put the classes that need to be enhanced spring container --> <bean name="ps" class="com.wang.service.impl.ProductService"></bean> <!-- Put the enhanced class spring container --> <bean name="myAdvice2" class="com.wang.test4.MyAdvice2"></bean> <!-- To configure AOP --> <aop:config> <!-- breakthrough point --> <aop:pointcut id="pc1" expression="execution(* com.wang.service..*ProductService.save())" /> <!-- Tangent (to cut the enhanced code into the target) --> <aop:aspect ref="myAdvice2"> <!-- Weaving pre reinforcement --> <!-- <aop:before pointcut-ref="pc1" method="beforeMethod" /> --> <!-- Final weaving enhancement whether or not an exception is thrown--> <!-- <aop:after pointcut-ref="pc1" method="afterMethod"/> --> <!-- Woven in surround enhancement --> <!-- <aop:around pointcut-ref="pc1" method="aroundMethod"/> --> <!-- Weaving in exception notification after the target method throws an exception --> <!-- <aop:after-throwing method="exceptionMethod" pointcut-ref="pc1"/> --> <!-- Abnormal weaving after insertion(Do not execute after exception) --> <aop:after-returning method="afterMethod2" pointcut-ref="pc1"/> </aop:aspect> </aop:config> </beans>
package com.wang.test4; import org.aspectj.lang.ProceedingJoinPoint; /** * Notification class. */ public class MyAdvice2 { /* * Spring Enhanced type: (notification is enhanced code, different notification types are the problem of where to put the enhanced code!) * (1)Pre enhancement: run the enhanced code before the target method runs. * (2)Post notification: after the target method runs (if no exception occurs), run the enhanced code. * (3)Orbit notification: before and after the target method runs, the enhanced code runs. * (4)Exception notification: if an exception occurs to the target method, the enhanced method is run. * (5)Post notification: run the enhanced code after the target method runs, whether or not an exception occurs. */ // Advance notice (name can be started at will) public void beforeMethod() { System.out.println("Pre notification code!"); } // Post notification public void afterMethod() { System.out.println("Post notification code!"); } // Around Advice public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("Orbit notification: previous code!"); // Call target method Object proceed = pjp.proceed(); System.out.println("Orbit notification: code after!"); return proceed; } // Exception notification public void exceptionMethod() { System.out.println("Abnormal.!"); } // Post notification public void afterMethod2() { System.out.println("Post notification(Exception will not be called)!"); } }
Define AOP with annotations
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd " > <!-- Classes to enhance --> <bean name="ps" class="com.wang.service.impl.ProductService" ></bean> <!-- Enhanced class --> <bean name="myAdvice1" class="com.wang.test5.MyAdvice1" ></bean> <bean name="myAdvice2" class="com.wang.test5.MyAdvice2" ></bean> <!-- aop Profile method for --> <!-- <aop:config> <aop:pointcut id="pc1" expression="execution(* com.wang.service..*ProductService.save())" /> <aop:aspect ref="myAdvice2"> <aop:before pointcut-ref="pc1" method="beforeMethod" /> <aop:after pointcut-ref="pc1" method="afterMethod"/> <aop:around pointcut-ref="pc1" method="aroundMethod"/> <aop:after-throwing method="exceptionMethod" pointcut-ref="pc1"/> <aop:after-returning method="afterMethod2" pointcut-ref="pc1"/> </aop:aspect> </aop:config> --> <!-- open aop Annotation method of --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
Insert a code slice here package com.wang.test5; 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; import org.aspectj.lang.annotation.Pointcut; /** * Customize a notification class. */ @Aspect // I am facet (enhancement in facet) public class MyAdvice2 { /* * If the expression of pointcut is the same, extract the expression of pointcut. * Add to a dedicated method! * The name of this method can be called directly below! */ // Annotation method to define an entry point. @Pointcut("execution(* com.wang.service..*Service.*(..))") public void pc(){} // Empty methods without any meaning // Use pointcuts. @Before("MyAdvice2.pc()") public void beforeMethod() { System.out.println("Pre notification code!"); } // Post notification // @After("MyAdvice2.pc()") // public void afterMethod() { // System.out.println("post notification (call in case of exception)!"); // } // // //Surround notification // @Around("MyAdvice2.pc()") // public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable { // System.out.println("surround notification: previous code!"); // // //Call target method // Object proceed = pjp.proceed(); // // System.out.println("surround notification: code after!"); // return proceed; // } // // //Post notice // @AfterReturning("MyAdvice2.pc()") // public void afterMethod2() { // System.out.println("post notification (no call in case of exception)"); // } // // //Exception notification // @AfterThrowing("MyAdvice2.pc()") // public void exceptionMethod() { // System.out.println("exception!"); // } }
automatic understanding of aop: in fact, aop is to extract the shared method, which is a facet. The pointcut in a specific class is the method that needs to be enhanced. We add the shared method to the pointcut, which is the method that needs to be enhanced, so as to improve the scalability and availability of the generation code, and to a certain extent, it is also conducive to decoupling.