AOP (Aspect Oriented Programming) is a technology that realizes horizontal multi-module unified control of program functions through precompilation and run-time dynamic proxy. AOP complements OOP and is an important part of the Spring framework. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development. AOP can be divided into static weaving and dynamic weaving. Static weaving refers to writing what needs to be woven into the target module before compilation, which is very expensive. Dynamic weaving does not require changing the target module. The Spring framework implements AOP, which is more convenient and intuitive to accomplish using annotation configuration than XML configuration. The proxy pattern was covered in detail in the last essay.

Explain the various ways Spring implements AOP

Spring AOP based on XML configuration

Before going into annotations to implement AOP functionality, I’ll use the Spring AOP functionality I’ve learned using XML to configure for comparison purposes.

1.1. Create a New Maven project and add a reference to it.

Explain the various ways Spring implements AOP

XML/HTML code


4.0.0

Com. Zhangguo Spring052 0.0.1 – the SNAPSHOT of the jar

Spring052

maven.apache.org

Java code

package com.zhangguo.Spring052.aop01;

/ * *

  • Public int add(int n1,int n2){int result=n1+n2; // Public int add(int n1,int n2){int result=n1+n2; System.out.println(n1+”+”+n2+”=”+result); return result; }

    // subtract public int sub(int n1,int n2){int result=n1-n2; System.out.println(n1+”-“+n2+”=”+result); return result; }

    Public int mut(int n1,int n2){int result=n1*n2; System.out.println(n1+”X”+n2+”=”+result); return result; }

    Public int div(int n1,int n2){int result=n1/n2; System.out.println(n1+”/”+n2+”=”+result); return result; The following code is used to edit the notification class ndep.java for AOP:

Java code

package com.zhangguo.Spring052.aop01;

import org.aspectj.lang.JoinPoint;

/ * *

  • Notification class, crosscutting logic

*/

public class Advices {

Public void before (JoinPoint jp) {System. Out. Println (" -- -- -- -- -- -- -- -- -- -- pre notice -- -- -- -- -- -- -- -- -- -- "); System.out.println(jp.getSignature().getName()); {} public void after (JoinPoint jp) System. The out. Println (" -- -- -- -- -- -- -- -- -- -- eventually notice -- -- -- -- -- -- -- -- -- -- "); }Copy the code

} 1.4 Configure the XML file required for container initialization. The content of the aOP01.xml file is as follows:

XML/HTML code

<! - the proxy object - > < bean id = "math" class = "com. Zhangguo. Spring052. Aop01. Math" > < / bean > <! -- notice -- -- > < bean id = "advices" class = "com. Zhangguo. Spring052. Aop01. Advices" > < / bean > <! --> <aop:config proxy-target-class="true"> < AOP :aspect ref="advices"> <! - tangent point - > < aop: pointcut expression = "execution (* com. Zhangguo. Spring052. Aop01. Math. * (..) )" id="pointcut1"/> <! <aop:before method="before" pointcut-ref="pointcut1"/> <aop:after method="after" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config>Copy the code

Java code

package com.zhangguo.Spring052.aop01;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("aop01.xml");  
    Math math = ctx.getBean("math", Math.class);  
    int n1 = 100, n2 = 5;  
    math.add(n1, n2);  
    math.sub(n1, n2);  
    math.mut(n1, n2);  
    math.div(n1, n2);  
}  
Copy the code

} Run result:

Explain the various ways Spring implements AOP

Configure AOP with annotations

Explain the various ways Spring implements AOP

2.1. Modify the propped class Math in the previous example by annotating @service on the Math class and naming the bean Math for IOC scanning. Equivalent to adding a bean to the XML configuration file in the previous example, the Math class code looks like this:

Java code

package com.zhangguo.Spring052.aop02;

import org.springframework.stereotype.Service;

/ * *

  • */ @service (“math”) public class math {// add public int add(int n1,int n2){int result=n1+n2; System.out.println(n1+”+”+n2+”=”+result); return result; }

    // subtract public int sub(int n1,int n2){int result=n1-n2; System.out.println(n1+”-“+n2+”=”+result); return result; }

    Public int mut(int n1,int n2){int result=n1*n2; System.out.println(n1+”X”+n2+”=”+result); return result; }

    Public int div(int n1,int n2){int result=n1/n2; System.out.println(n1+”/”+n2+”=”+result); return result; There are three annotations in “@Component” to indicate that instances of this class are managed by the Spring IOC container. @Aspect declares a facet; @before indicates that Before is a pre-notification and a cut point is declared using the execution parameter, as shown in the following code:

Java code

package com.zhangguo.Spring052.aop02;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

/ * *

  • Notification class, crosscutting logic

/ @Component @Aspect public class Advices { @Before(“execution( com.zhangguo.Spring052.aop02.Math.*(..) ) “public void before (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — pre notice — — — — — — — — — –“); System.out.println(jp.getSignature().getName()); }

@After("execution(* com.zhangguo.Spring052.aop02.Math.*(..) ) "public void after (JoinPoint jp) {System. Out. Println (" -- -- -- -- -- -- -- -- -- -- eventually notice -- -- -- -- -- -- -- -- -- --"); }Copy the code

} The code above is basically the same as the configuration below

XML/HTML code





The Spring framework automatically creates a proxy for a Bean configured with AspectJ aspects. The proxy-target-class=”true” attribute indicates that the target object being propped is a class, not a class that implements the interface, mainly to choose a different proxy.

XML/HTML code



Java code

package com.zhangguo.Spring052.aop02;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("aop02.xml");  
    Math math = ctx.getBean("math", Math.class);  
    int n1 = 100, n2 = 5;  
    math.add(n1, n2);  
    math.sub(n1, n2);  
    math.mut(n1, n2);  
    math.div(n1, n2);  
}  
Copy the code

} Run result:

Explain the various ways Spring implements AOP

AspectJ pointcut functions

Point of tangency function can locate to the accurate position of crosscutting logic, we only used in the previous example execution (* com. Zhangguo. Spring052. Aop02. Math. * (..) Execution is a pointcut function, but it has only one level of method execution. If we are weaving into a class or an annotation, execution is less useful. There are nine pointcut functions, all of which have different meanings.

AspectJ uses AspectJ-specific pointcut expressions to describe sections. The AspectJ expressions supported by Spring fall into four categories:

Method pointcut functions: Define join points by describing target class method information.

Method parameter pointcut function: defines join points by describing the target class method input parameter information.

Target class pointcut function: defines join points by describing target class type information.

Proxy class pointcut functions: Define join points by describing proxy class information.

Common AspectJ expression functions:

Execution () : Join points for all target class methods that satisfy the matching pattern string

Annotation () : Any target method link point that annotates the specified annotation

Args () : The type of the run-time parameter of the target class method specifies the join point

@args() : Whether there are join points in the target class method parameters that specify specific annotations

Within () : matches all join points of the specified package

Target () : Matches all methods of the specified target class

@WITHIN () : Matches all methods of the class whose target object has the specified annotation

@target() : execution method that matches the current target object type, where the target object holds the specified annotation

This () : Matches all execution methods of the current AOP proxy object type

The most common is: Execution (< modifier pattern >? < return type mode >< method name mode >(< parameter mode >)< exception mode >? Tangent point functions can satisfy most needs.

To demonstrate the function of each tangent point, we now add a new class StrUtil:

Java code

package com.zhangguo.Spring052.aop03;

import org.springframework.stereotype.Component;

@Component(“strUtil”) public class StrUtil { public void show(){ System.out.println(“Hello StrUtil!” ); }} The test code is as follows:

Java code

package com.zhangguo.Spring052.aop03;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {  
    ApplicationContext ctx = new ClassPathXmlApplicationContext("aop03.xml");  
    IMath math = ctx.getBean("math", Math.class);  
    int n1 = 100, n2 = 5;  
    math.add(n1, n2);  
    math.sub(n1, n2);  
    math.mut(n1, n2);  
    math.div(n1, n2);  
      
    StrUtil strUtil=ctx.getBean("strUtil",StrUtil.class);  
    strUtil.show();  
}  
Copy the code

} execution of the execution of the point function

Java code

package com.zhangguo.Spring052.aop03;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

/ * *

  • Notification class, crosscutting logic

/ @Component @Aspect public class Advices { @Before(“execution( com.zhangguo.Spring052.aop03.Math.*(..) ) “public void before (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — pre notice — — — — — — — — — –“); System.out.println(jp.getSignature().getName()); }

/ / execution tangent point function. / / com zhangguo. Spring052. Aop03 package all methods of all classes are cut into the @ After (" execution (* com. Zhangguo. Spring052. Aop03. *. * (..) ) "public void after (JoinPoint jp) {System. Out. Println (" -- -- -- -- -- -- -- -- -- -- eventually notice -- -- -- -- -- -- -- -- -- --"); }Copy the code

} The result is as follows:

Explain the various ways Spring implements AOP

Execution (< modifier pattern >? < return type mode >< method name mode >(< parameter mode >)< exception mode >?

3.2. The tangent function within

Java code

/ / the within the tangent point function. / / com zhangguo. Spring052. Aop03 package all methods of all classes are cut into the @ After (” within (com) zhangguo. Spring052. Aop03. *) “) public void After (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — eventually notice — — — — — — — — — — “); Explain the various ways Spring implements AOP

3.3. This tangential function

Java code

/ / / / this tangent point function realized IMath interface proxy objects of arbitrary points @ After (” this (com) zhangguo. Spring052. Aop03. IMath) “) public void After (JoinPoint jp) { System.out.println(“———- final notification ———-“); Explain the various ways Spring implements AOP

3.4. Args tangent function

Java code

@after (“args(int,int)”) public void After(JoinPoint jp){public void After(JoinPoint jp){ System.out.println(“———- final notification ———-“); Explain the various ways Spring implements AOP

The package name is required if the parameter type is not a basic data type.

3.5. @annotation Points function

Start with a custom annotation that can be annotated on a method

Java code

package com.zhangguo.Spring052.aop03;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target({elementtype.method}) @Retention(RetentionPolicy.runtime) @Documented Public @interface MyAnno {} Java code

/ / / / @ the annotation tangent point function request method must be annotated com. Zhangguo. Spring052. Aop03. MyAnno will be woven into the crosscutting logic @After(“@annotation(com.zhangguo.Spring052.aop03.MyAnno)”) public void after(JoinPoint jp){ System.out.println(“———- final notification ———-“); } Java code

package com.zhangguo.Spring052.aop03;

import org.springframework.stereotype.Component;

@Component(“strUtil”) public class StrUtil { @MyAnno public void show(){ System.out.println(“Hello StrUtil!” ); }} Run result:

Explain the various ways Spring implements AOP

All other pointcut functions with @ are for annotations

AspectJ notification annotations

There are six AspectJ notification annotations, five of which are commonly used, and fewer introductions.

First solve the problem of defining pointcut reuse, as shown in the following code, the content of pointcut function is exactly the same:

Java code

package com.zhangguo.Spring052.aop04;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

/ * *

  • Notification class, crosscutting logic

/ @Component @Aspect public class Advices { @Before(“execution( com.zhangguo.Spring052.aop04.Math.*(..) ) “public void before (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — pre notice — — — — — — — — — –“); System.out.println(jp.getSignature().getName()); }

@After("execution(* com.zhangguo.Spring052.aop04.Math.*(..) ) "public void after (JoinPoint jp) {System. Out. Println (" -- -- -- -- -- -- -- -- -- -- eventually notice -- -- -- -- -- -- -- -- -- --"); }Copy the code

} you can define a pointcut and reuse it as follows:

Java code

package com.zhangguo.Spring052.aop04;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.stereotype.Component;

/ * *

  • Notifier, crosscutting logic / @ Component @ Aspect public class Advices {/ / cutting the @pointcut (” execution (… Com zhangguo Spring052 aop04. Math. * (..) )”) public void pointcut(){ }

    @ Before (pointcut “()”) public void Before (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — pre notice — — — — — — — — — — “); System.out.println(jp.getSignature().getName()); }

    @ After (pointcut “()”) public void After (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — eventually notice — — — — — — — — — — “); }} Modify the Advices. Java file to add the following notification types:

Java code

package com.zhangguo.Spring052.aop04;

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;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.stereotype.Component;

/ * *

  • Notifier, crosscutting logic / @ Component @ Aspect public class Advices {/ / cutting the @pointcut (” execution (… Com zhangguo Spring052 aop04. Math. A * (..) )”) public void pointcut(){ }

    @before (“pointcut()”) public void Before(JoinPoint jp){system.out.println (jp.getSignature().getName()); System.out.println(“———- pre-notification ———-“); }

    / / final notice @ After (pointcut “()”) public void After (JoinPoint jp) {System. Out. Println (” — — — — — — — — — — eventually notice — — — — — — — — — — “); }

    / / Around notice @ Around (” execution (* com. Zhangguo. Spring052. Aop04. Math. S * (..) )”) public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println(pjp.getSignature().getName()); System.out.println(“———- surround front ———-“); Object result=pjp.proceed(); System.out.println(“———- surround ———-“); return result; }

    / / return the result notification @ AfterReturning (execution pointcut = “(. * com. Zhangguo Spring052. Aop04. Math., m * (..) )”,returning=”result”) public void afterReturning(JoinPoint jp,Object result){ System.out.println(jp.getSignature().getName()); System.out.println(” result: “+result); System.out.println(“———- return result ———-“); }

    / / exception after notification @ AfterThrowing (execution pointcut = “(. * com. Zhangguo Spring052. Aop04. Math. D * (..) )”,throwing=”exp”) public void afterThrowing(JoinPoint jp,Exception exp){ System.out.println(jp.getSignature().getName()); System.out.println(” exception message: “+exp. GetMessage ()); System.out.println(“———- error notification ———-“); }} Run result:

Explain the various ways Spring implements AOP

Zero configuration implementation of Spring IoC and AOP

In order to achieve zero configuration, we added a new class User on the basis of the original example, as follows:

Java code

package com.zhangguo.Spring052.aop05;

Public class User {public void show(){system.out.println (” a User object “); }} The class is not annotated and the container is not automatically managed. Since there is no XML configuration file, one is used as configuration information, the applicationcfg.java file is as follows:

Java code

package com.zhangguo.Spring052.aop05;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ Configuration / / used to represent the Configuration of the current class for container classes, like @ ComponentScan (basePackages = “com. Zhangguo. Spring052. Aop05”) / / the scope of scanning, Context :component-scan/ @enableAspectJAutoProxy (proxyTargetClass=true) // Automatic proxy,
@bean public User getUser(){return new User(); }} Each part of this class basically has a one-to-one relationship with the XML configuration, as you can see in the comments. This is easier than writing XML, but not easy to change after publishing. The test code is as follows:

Java code

package com.zhangguo.Spring052.aop05;

import org.springframework.context.ApplicationContext;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

Public static void main(String[] args) {// Initialize the container ApplicationContext CTX = new AnnotationConfigApplicationContext(ApplicationCfg.class); Math math = ctx.getBean("math", Math.class); int n1 = 100, n2 = 0; math.add(n1, n2); math.sub(n1, n2); math.mut(n1, n2); try { math.div(n1, n2); } catch (Exception e) { } User user=ctx.getBean("getUser",User.class); user.show(); }Copy the code

} nadvices. Java as above, no change, and the result is as follows:

Explain the various ways Spring implements AOP

If you want to learn Java engineering, high performance and distributed, simple. Performance tuning, Spring, MyBatis, Netty source code analysis of friends can add my Java advanced architecture advanced group: 180705916, group ali Daniel live explained technology, as well as Java large Internet technology video free to share to you