What is the AOP

AOP (aspect-orientedProgramming, aspect-oriented programming) can be said to be OOP (Object-oriented Programing, object-oriented programming) complement and perfect. OOP programs vertically by inheriting parent classes and implementing interfaces, which spreads business-neutral code across classes, such as logging capabilities and permission authentication. It leads to a lot of code duplication and is not conducive to reuse of modules.

AOP, on the other hand, uses a technique called “crosscutting” to peel apart the insides of wrapped objects and encapsulate common behavior that affects multiple classes into a reusable module called an “Aspect, “or section. The so-called “aspect”, simply speaking, is to encapsulate the logic or responsibility that has nothing to do with the business, but is called by the business modules together, so as to reduce the repetitive code of the system, reduce the degree of coupling between modules, and facilitate the future operability and maintainability.

AOP represents a horizontal relationship, if the “object” is a hollow cylinder that encapsulates the properties and behavior of the object. Aspect-oriented programming, then, is like a sharp knife, cutting open these hollow cylinders to get information inside them. And the cut surface is the so-called “aspect”. Then, with a masterful hand, it restored the cut surfaces without leaving a trace.

AOP technology, mainly divided into two categories: one is the use of dynamic proxy technology, using the interception of the message to decorate the message, to replace the original object behavior implementation; The other is static weaving, which introduces special syntax to create “aspects” so that the compiler can weave code about “aspects” at compile time.

AOP related concepts

  • Joinpoint

Join points are methods that need to be enhanced. Spring only supports method join points, which can only be enhanced at these program execution points before, after, and before method calls.

  • Pointcut

AOP locates join points through pointcuts. Understand pointcuts and join points in terms of database queries: join points correspond to records in database tables, while pointcuts correspond to query conditions. Join points and cut points are not one-to-one correspondence, one cut point can match multiple join points.

  • Advice

An enhancement is a piece of program code woven into the target class join point.

  • Target Object

Enhanced logic weaving into the target class. Without AOP, the target business class would need to implement all the logic itself. With THE help of AOP, the target class implements only the program logic that is not crosscutting logic, while the rest of the code can use AOP to dynamically weave into specific join points.

  • Introduction

Introduction is a special enhancement that adds attributes and methods to a class, so that even if a business class does not originally implement an interface, AOP’s introduction allows us to dynamically add the implementation logic of the interface to that business class, making it the implementation class of that interface.

  • Weaving

Weaving is the process of adding enhancements to specific join points for target classes. AOP is like a loom that weaves together target classes, enhancements, or introductions.

  • Proxy

When a class is woven and enhanced by AOP, the result class is a proxy class that combines the original class with the enhanced logic.

  • Aspect

An aspect consists of pointcuts and enhancements. It includes both the definition of crosscutting logic and the definition of join points. Spring AOP is the framework responsible for implementing the aspect by weaving the crosscutting logic defined by the aspect into the join points specified by the aspect.

Realize the principle of

The proxy pattern

To create a proxy object for an object, we do not refer directly to the original object, but the proxy object created controls the reference to the original object. The proxy pattern is a common Java design pattern in which proxy objects contain internal references to real objects so that they can operate on them and provide the same interface as real objects so that they can replace real objects at any time. At the same time, a proxy object can perform operations on the real object with additional operations attached, which is equivalent to encapsulating the real object.

Proxy classes can be divided into two categories, depending on when the agent was created:

  • Static agent

Source code is created by programmers or automatically generated by specific tools and then compiled. The.class file for the proxy class exists before the program runs.

  • A dynamic proxy

When the program runs, the use of reflection mechanism to create dynamic, without manual code. Dynamic proxies not only simplify programming but also improve the extensibility of software systems because Java reflection can generate any type of dynamic proxy class.

The implementation principle of AOP

Spring implements AOP using dynamic proxies, using the DYNAMIC proxy technology provided by the JDK and CHLIB (dynamic bytecode enhancement technology).

JDK dynamic proxy

  • JDK dynamic proxies are interface oriented and must provide an interface that both the delegate class and the proxy class implement. Only methods in the interface can be proxied.
  • JDK dynamic proxies are implemented using the Proxy class in the java.lang.Reflect package and the InvocationHandler interface.

CGLIB dynamic proxy

Using very low-level bytecode technology, CGLIB can create a subclass of a class and use method interception techniques in that subclass to intercept all calls to parent methods and embed crosscutting logic as appropriate. We inherit the proxied object and Override the proxied method. We can insert our own code when overriding the proxied method. Because you need to Override the methods of the propped object, implementing AOP naturally with CGLIB technology requires that the methods to be propped cannot be final methods, since final methods cannot be overridden by subclasses.

Summary of JDK agents and CGLIB agents

Dynamic proxy objects created by CGLIB perform much better than those created by the JDK, but they take longer to create than the JDK.

If the target object implements the interface, the DEFAULT implementation of AOP is the JDK’s dynamic proxy, which implements the interface using the CGLIB proxy.

Use of AOP annotations

Execution expression

** ( com.sample.service.impl .. .(..) )* * *

symbol meaning
Execute () Body of an expression
The first “*” Represents the return value of any type
com.sample.service.impl The package name of the service that the AOP cuts
The “..” after the package name Represents the current package and its subpackages
The second “*” *Represents the class name,All class
. * (..) Represents any method name, any parameter type

notice

Custom annotation

@Target({ ElementType.METHOD, ElementType.TYPE })  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface AnnotationName {  
	String key(a) default "value";
}  
Copy the code

Define the plane

@Component  
@Aspect  
public class AspectName {  
    // Use annotations to define pointcuts
    @Pointcut("@annotation(com.feng.AnnotationName)")  
    public void methodPointcut(a) {}// Use execution expressions to define pointcuts
    @Pointcut("execution(* com.sample.service.impl.. *. * (..) )"
    public void point(a){}
    
    @Around("methodPointcut()")  
    public Object around(ProceedingJoinPoint point) throws Throwable {}}Copy the code

Invalid AOP annotations

In the same class, method A calls method B (with an annotation on method B). The annotation is invalid.

public class A {
    public void a(a) {
        b();
    }
    
    public void b(a) {}}Copy the code
// The generated proxy class
public class A$Proxy {
    A serviceA = new A();
    
    public void a(a) {
        serviceA.a();
    }
    
    public void b(a) {
        transaction start(a);
        serviceA.b();
        transaction end(a); }}Copy the code

If we call the Bean A to actually call AProxy, the call to method A is actually to call A method in A, and A in A calls b method in A, and does not call B method in AProxy to implement the transaction.

The solution

// 2. Get the proxy object and call B.
((ClassName)AopContext.currentProxy()).B()
Copy the code