It will mainly explain the basics of AOP and the different uses.

preface

Learning Spring AOP, began to think that the knowledge of AOP will be a lot, but compared with IOC knowledge, found a lot less, but if put in an article, feeling is still a bit long, will be divided into the next two parts, to explain this knowledge.

The update of these two days is a little slow, I feel not so good, maybe I got up too early in the morning, the efficiency is not too high, I will have a good rest on the weekend to adjust the state.

About AOP

AOP overview

If IoC is at the heart of Spring, then faceted programming is one of its most important features.

  • Aspect oriented programming (AOP) is a programming pattern similar to object oriented programming (OOP). Spring AOP is a framework based on AOP programming pattern. Its use effectively reduces the duplication of code between systems and achieves the purpose of loose coupling between modules.
  • AOP’s full name is “Aspect Oriented Programming”, that is, section-oriented Programming, it will be separated from each part of the business logic, so that developers can focus on the core business when writing business logic, thus improving the development efficiency.
  • AOP adopts horizontal extraction mechanism to replace the repetitive code of traditional vertical inheritance system, and its application is mainly reflected in transaction processing, log management, authority control, exception handling and so on.
  • Two of the most popular AOP frameworks are Spring AOP and AspectJ:
    • Spring AOP uses a pure Java implementation that does not require a specialized compilation process or classloader and proxies enhanced code into target classes at run time.
    • AspectJ is an AOP framework based on the Java language. Beginning with Spring 2.0, Spring AOP introduced support for AspectJ. AspectJ extends the Java language by providing a specialized compiler that provides cross-coding at compile time.

Section-oriented programming

First of all, in the idea of section-oriented programming, functions are divided into core business functions and peripheral functions:

  • The so-called core business, such as logging in, adding data, deleting data are called core business
  • So-called peripheral functions, such as performance statistics, logging, transaction management, etc

Peripheral functions are defined as facets in Spring’s faceted programming AOP thinking. In the idea of aspect oriented programming AOP, the core business functions and aspect functions are developed separately, and then the aspect functions and core business functions are “woven” together, which is called AOP.

AOP can encapsulate logic or responsibilities (such as transaction processing, log management, permission control, etc.) that have nothing to do with the business but are commonly invoked by business modules, which is easy to reduce the duplication of code in the system, reduce the degree of coupling between modules, and facilitate future scalability and maintainability.

AOP basics

Basic concept

To better understand AOP, you need to understand some of the terminology associated with AOP, which includes Joinpoint, Pointcut, Advice, Target, Weaving, Proxy, and Aspect, as shown in the following table.

This is a bit abstract, but let’s take it a step further:

  • Aspect: Aspect declarations are similar to class declarations in Java, and transaction management is one of the most typical uses of AOP. In AOP, aspects are typically used using the @aspect annotation, and in XML, you can use < AOP: Aspect > to define an Aspect.
  • Join Point: an operation during the execution of a program, such as executing a method or handling an exception. In Spring AOP, a join point represents the execution of a method.
  • Advice: Action taken at a join point (method) in the section. There are four different types of Advice: around, before, after, exception, and return. Many AOP frameworks, including Spring, will recommend advice as interceptors and maintain a series of interceptors around join points.
  • Pointcut: Represents a set of join points, with advice associated with a Pointcut expression and running at any join point that the Pointcut matches (for example, executing a method with a specific name). The concept of join points matched by pointcut expressions is at the heart of AOP, and Spring uses the AspectJ pointcut expression language by default.
  • Introduction: Introduction can add new properties and methods to existing objects. For example, you can use Introduction to make the bean implement the IsModified interface to simplify caching.
  • Target Object: An Object that is represented by one or more facets. Also known as “slice object”. Since Spring AOP is implemented using a runtime proxy, this object is always a proxy object.
  • AOP Proxies: Objects created by an AOP framework. In the Spring framework, THERE are two types of AOP proxy objects: JDK dynamic proxies and CGLIB proxies
  • Weaving is the process of applying enhancements to target objects to create new proxy objects, which (like the AspectJ compiler) can be done at compile time, load time, or run time. Like other pure Java AOP frameworks, Spring AOP is woven at run time.

What? Or is it a little loopy? Can look at the following god summary, concise and comprehensive, if you do not understand, that floor brother also can not do.

  • Pointcut: Which classes and methods to cut into
  • Advice: what to do (when: before method/after method/before and after method) when method is executed (what: enhanced functionality)
  • Aspect = pointcut + notification, popular point is: when, where, what to do enhancement!
  • Weaving: The process of adding facets to objects and creating proxy objects. (Done by Spring)

Classification of notices

  • Before Advice: call notification Before the target method is called; Related classes org. Springframework. Aop. MethodBeforeAdvice
  • After Advice: call Advice After the target method is called; Related classes org. Springframework. Aop. AfterReturningAdvice
  • After-returning: Notification is called After successful execution of the target method;
  • After-throwing: invoking notification After the target method throws an exception; Related classes org. Springframework. Aop. ThrowsAdvice
  • Surrounding the notification (Around) : the whole target method, and call after call respectively before the called notifications related class org. Aopalliance. Intercept. MethodInterceptor

The three periods that AOP weaves into

  • Compile-time: The aspect is woven in when the target class is compiled, which requires a special compiler. AspectJ’s weaving compiler weaves facets in this way.
  • Class loading time: The aspect is woven into the TARGET class when it is loaded into the JVM. This approach requires a special ClassLoader that enhances the bytecode of the target class before it is introduced into the application.
  • Run-time: Facets are woven in at some point during the application run. Typically, when weaving into facets, the AOP container dynamically creates a proxy object for the target object, and Spring AOP takes this weaving approach.

A simple EXAMPLE of AOP

The best way to learn a language is to use it in real time. Let’s skip the rest of the introduction and look directly at a specific example of use. Let’s define an implementation class:

@Component("customerDao")
public class CustomerDaoImpl {
    public void add(a) {
        System.out.println("Add customer...");
    }
    public void update(a) {
        System.out.println("Modify customer...");
    }
    public void delete(a) {
        System.out.println("Delete customer...");
    }
    public void find(a) {
        System.out.println("Modify customer..."); }}Copy the code

Then define a section class:

@Component
public class MyAspect {
    // Pre-notification
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("Pre-notification, method name: + joinPoint.getSignature().getName());
    }
    // post notification
    public void myAfterReturning(JoinPoint joinPoint) {
        System.out.println("Postnotification, method name:" + joinPoint.getSignature().getName());
    }
    // Wrap around the notification
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Start around"); / /
        Object obj = proceedingJoinPoint.proceed(); // Execute the current target method
        System.out.println("Wrap end"); / / end
        return obj;
    }
    // Exception notification
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("Exception notification, error.");
    }
    // Final notification
    public void myAfter(a) {
        System.out.println("Final notice"); }}Copy the code

It is important to add the appropriate configuration to the applicationContext.xml file:

<! --> <context:component-scan base-package="com.java.spring.aop.xml2" />
<context:component-scan base-package="com.java.spring.aop.customer"/ > <! <aop:aspectj-autoproxy></ AOP :aspectj-autoproxy><! --> < AOP :config> < AOP :aspect ref="myAspect"> <! < AOP :pointcut expression="execution (* com.java.spring.aop.customer.*.* (..) )" id="myPointCut"/ > <! < AOP :before method="myBefore" pointcut-ref="myPointCut"/ > <! Aop: returning method= < AOP: post-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal"/ > <! --> < AOP :around method="myAround" pointcut-ref="myPointCut"/ > <! Throw notification: used to handle exceptions that can be received from the current method --> <! -- * Note: Enhancement will not be performed if the program has no exceptions --> <! -- * Throwing property: set the name of the notification second parameter, type Throwable --> < AOP :after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/ > <! Aop :after method= aop:after method="myAfter" pointcut-ref="myPointCut" />
    </aop:aspect>
</aop:config>
Copy the code

You have to turn on “make aspects on autoproxy”, otherwise AOP won’t work because I inject automatically through annotation scanning, so don’t forget “for annotation scanning” because my CustomerDaoImpl and MyAspect are under xml2 and Customer respectively. So we need to scan these two packets.

For the following one, I think many students will be in a state of confusion when they see this one:

execution (* com.java.spring.aop.customer.*.* (..) )Copy the code

This is actually a Spring AOP expression:

Execution of any public method: execution(public* * (..) ) # #publicThe first * represents any return value of the method and the second argument represents any package + class + method (..). Execution of any method beginning with "get" for any argument: Execution (* get*(..)) Any method) UserService interface: execution (* com. Einblatt. Service. UserService. * (..) Execution of any method defined in the com.einblatt.service package: execution(* com.einblatt.service.*.*(..)) The first.* represents any class, and the second.* represents the execution of any method of any class defined in the service package and all subpackages. *. * (..) ) #.. * Represents the execution of any method of the UserService class defined in the com.einblatt package and all subpackages: execution(* com.einblatt.. UserService.*(..) )Copy the code

We’ll review the expression of the above, the first “asterisk” said any return value, com. Java. Spring. Aop. Custome is need to strengthen the package path of object, the second “star” said all the files in this package path, the third “asterisk” said file class all the way, the last two “..” Can be any parameter.

The editor can’t use the “*” symbol directly, it will be used as a typesetting symbol, I used “asterisk” instead.

For the rest of the applicationContext.xml file, we configure the aspect myAspect, define the pointcut myPointCut for the aspect, and then configure the pre, post, wrap, throw exception, and final notification for that pointcut, so when we execute the methods in the pointcut, Are enhanced by methods in the facets, as shown in the following example:

public class XMLTest {
    @Test
    public void test(a) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        CustomerDaoImpl customerDao = (CustomerDaoImpl) applicationContext.getBean("customerDao");
        // Execute methodcustomerDao.add(); }}/ / output:
// Pre-notification, method name :add
// Wrap around start
// Add client...
// Final notification
// Wrap around end
// After the notification, method name: add
Copy the code

Our core method outputs “Add customer…” Here, AOP adds pre-notification, surround notification, final notification, and post-notification. You can see the call order and test the throw notification. We modify CustomerDaoImpl as follows:

@Component("customerDao")
public class CustomerDaoImpl {
    public void add(a) throws Exception {
        System.out.println("Add customer...");
        throw new Exception("Throw exception test");
    }
    // ...
}
Copy the code

Pass the above sample test again, and the output is as follows:

Pre notification, method name :add Surround start add customer... Finally notify exception notification, errorCopy the code

You can see that throwing an exception reinforces the output “exception notification, error”, but the following “wrap end” and “post-notification” are missing.

You should get a start on AOP with this simple example, which is based on AspectJ’s XML implementation. In fact, There are many ways to achieve AOP in JAVA, the following we on the existing implementation of the way, a whole introduction, so that we have a macro understanding.

Two implementations of AOP

There are two implementations of AOP: static weaving (AspectJ implementation) and dynamic proxying (Spring AOP implementation)

  • Static weaving (AspectJ implementation) : Can be divided into DECLARative XML-based and annotation-based. (The above example is AspectJ’s XML-based declarative form)
  • Dynamic proxy (Spring AOP implementation) : can be divided into JDK dynamic proxy and CGLib dynamic proxy.

So to be precise, there are really four implementations of AOP.

AspectJ

  • AspectJ is an AOP framework implemented in Java that compiles code (typically at compile time) to give it AspectJ’s AOP capabilities.
  • AspectJ is currently the most mature and feature-rich language for implementing AOP frameworks.
  • ApectJ takes a compile-time statically woven approach. During this time, AspectJ’s ACJ compiler (similar to JavAC) is used to encode aspect classes into class bytecodes, which are woven into the Java target classes at compile time, that is, compile the aspect classes first and then the target classes.

Spring AOP implementation

Spring AOP is implemented through dynamic proxy technology, which is based on reflection design. Spring AOP uses two hybrid implementations: JDK dynamic proxy and CGLib dynamic proxy.

  • JDK dynamic Proxies: Spring AOP’s preferred approach. JDK dynamic proxies are used every time the target object implements an interface. The target object must implement the interface
  • CGLIB proxy: If the target object does not implement an interface, the CGLIB proxy can be used.

Due to the length of this article, there are four implementations of AOP, and there are three that are not exemplified, but I will give a full example description in the next article.

conclusion

In this article, you’ll be able to get the basics of AOP and get a feel for the use of AOP. The most commonly used project so far is actually AspectJ’s Annotation based declaration. The next article will give a full example. We’ll talk about that in our next post.

Welcome everyone to like a lot, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point attention, do not get lost ~~