What is the AOP

AOP (Aspect Orient Programming) is Aspect oriented Programming, which is a Programming idea and a supplement of OOP.

Object-oriented programming abstracts the program into objects at various levels, while aspect – oriented programming abstracts the program into aspects. That is, modularized units in OOP are classes, while modularized units in AOP are aspects.

The AOP framework is an important part of Spring. But the Spring IoC container doesn’t rely on AOP, which means you have the option to use AOP or not, and AOP complements the Spring IoC container, making it a powerful middleware solution.


AOP’s role — Horizontal cutting (extraction)

As mentioned above, AOP is a complement to OOP.

When will there be a need for AOP?

According to the idea of software refactoring, if there are duplicate codes in multiple classes, we should consider defining a common abstract class and extract these common codes into the abstract class, such as Teacher, Student have username, Username and the related GET and set methods can be extracted into SysUser, which is called vertical extraction. But if you want to add performance checks and transaction control to all class methods, how do you extract? Now, OOP is clearly not enough to meet the needs, and AOP wants to extract the same code scattered across the business logic code into a separate module by cutting it horizontally, keeping the business logic classes pristine and letting developers focus on writing business processes.

Taking database operations as an example, the following steps are required to execute an SQL command in a project:

  1. Get the connection object
  2. Execute SQL (core business code)
  3. If there is an exception, the transaction is rolled back, and if there is no exception, the transaction is committed
  4. Close the connection

Step 2 of the above steps is the core business code, the rest is non-core business code, but we have to write. Faceted programming is designed to solve this problem by stripping away the non-core business code so that developers can only focus on the core business code. Its flow chart is as follows:

The following is a piece of code in the Spring + Mybatis project. The function is to purchase an item, update the item quantity and save the order. If there is an exception, the transaction will be rolled back.

public void savePurchaseRecord(Long productId, PurchaseRecord record) {
    SqlSession sqlSession = null;
    try{
        sqlSession = SqlSessionUtil.openSqlSession();
        ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
        Product product = productMapper.getProduct(productId); 
		// Determine whether the inventory is greater than the purchased quantity
		if(product.getStock() >= record.getQuantity()) {
			// Reduce inventory and update database records
			product.setStock(product.getStock() - productMapper.update(product) ; 
			// Save transaction recordspurchaseRecordMapper.save(record); }}catch(Exception e) {
        e.printStackTrace();
        sqlSession.rollback();
    } finally {
        if(sqlSession ! =null) sqlSession.close(); }}Copy the code

As you can see from the above code, the main flow we are interested in is inside the try block, and in order to execute the associated SQL, we have to write a try… The catch… Finally statement, so it looks like the whole block of code is bloated, so if we use sections to extract these non-core business process code into separate modules, then we don’t have to pay attention to and write such tedious code.

Taking a look at the AOP support in Spring, we can rewrite this code as follows:

@Autowired
private ProductMapper productMapper = null; 
@Autowired 
private PurchaseRecordMapper purchaseRecordMapper = null;
@Transactional 
public void savePurchaseRecord(Long productid, PurchaseRecord record) {
	Product product = productMapper.getProduct(productId); 
	// Determine whether the inventory is greater than the purchased quantity
	if(product.getStock() >= record.getQuantity()) {
		// Reduce inventory and update database records
		product.setStock(product.getStock() - productMapper.update(product) ; 
		// Save transaction recordspurchaseRecordMapper.save(record); }}Copy the code

How’s that? There is no code to open or close a database resource, let alone commit or roll back a database transaction, except for an AOP annotation called @Transactional. This code is cleaner and easier to maintain, and it focuses on business processing rather than database transactions and resource management, which is the beauty of AOP.


AOP principle

As shown in the above code, why we added annotations @ Transactional, can realize the database connection, transaction rollback operations such as?

Here we start with the concept of convention over configuration. Instead of worrying about the specifics of @Transactional’s implementation, let’s look at what it provides for Transactional:

  • When the method is labeled as@ Transactional, the method enables the database transaction function.
  • By default, if the original method fails, the transaction is rolled back. If no exception occurs, the transaction is committed, and the entire transaction management AOP completes the process without requiring the developer to write any code to implement it.
  • Finally, close the database resource.

Once we know the convention, we can use it directly. But if you want to get into AOP, it’s easy to understand. First of all, you should start with its functionality. What AOP does is to execute some method in some class and do some operation before and after the execution of the method.

Painted painted painted by dynamic proxy approach, AOP is a blocker on real object, to control all the cut surface of the object operation environment, management including log, database transactions, such as operation, can let we have in the reflection of the original object method before return to normal and abnormal return after the event’s ability to insert your own logic code, sometimes even to replace the original method.

For those unfamiliar with interceptors and how they work, you can read my previous two articles:

  • JDK dynamic proxy mode
  • This paper introduces the implementation of interceptor and interceptor chain

AOP related terms

Section (Aspect)

Some extraction of common operations, or modularization of a concern that may crosscut multiple objects.

Such as database transactions directly in the code above throughout the code level, and this is one aspect, it can be executed in the proxy object method before and after, produce abnormal or normal return into your code, or even replace the proxy object method, in the dynamic proxy can understand it’s a blocker.

Join Point

At a specific point in the execution of a program, such as when a method is called or when an exception is handled. In Spring AOP, a join point represents the execution of a method. In plain English, this method is a join point at which method execution needs to start intercepting to perform its own defined enhanced logic.

Pointcut

If a join point is specific to a method execution, then a tangent point can be understood as a collection of methods of a class that defines a scope. Because not all development requires AOP to be enabled, regular expressions are usually qualified to specify that some class of method is executed when AOP functionality is enabled.

Advice

Notification is a method in a slice when the slice is open. It is distinguished by order and logic before and after the actual method invocation of the proxy object.

  • Before notification: Notification performed before the dynamic proxy reflects the original object method or executes the surround notification.
  • Post-notification (after) : Notification after the dynamic proxy reflects the original object method or executes the surround notification. An exception is executed whether or not it is thrown.
  • AfterReturning: Notification that is performed after the dynamic proxy reflects an old object method or after it has executed a circular notification.
  • AfterThrowing: Notification that is performed after the dynamic proxy reflects an existing object method or executes an exception generated by the surround notification.
  • AroundThrowing: In a dynamic proxy, it replaces the current method of the object being blocked by providing a callback to the original method of the object being blocked.

Weaving

Weaving is actually a process: when the program executes at the join point, the proxy object is generated and the aspect content is put into the process.

AOP flowcharts are as follows:


Use of Spring AOP

To better understand the above concepts, let’s use a simple example to demonstrate the use and implementation of AOP.

We chose to use the Spring framework, which only supports method interception, and we used an annotation-based approach to configuration development. This simple test project functions as an AOP join point to the method of printing user information, enabling the ability to perform related operations before and after printing user information.

One Select the connection point

As mentioned above, the join point is which method to intercept and weave in the corresponding AOP advice. We create the following interface to declare the method of printing user information:

public interface RoleService {
    void printRole(Role role);
}
Copy the code

Then we provide an implementation class:

package com.codergeshu.aop.service.impl; // The location of the package
@Component
public class RoleServiceImpl implements RoleService {
    @Override
    public void printRole(Role role) {
        System.out.println("{id: " + role.getId() + ","
                + "role_name : " + role.getRoleName() + ","
                + "note : " + role.getNote() + "}"); }}Copy the code

There is nothing special about this class, except that if printRole is used as an AOP join point at this point, the dynamic proxy generates proxy objects for the RoleServicelmpl class and then intercepts printRole methods, thus generating various AOP notification methods.

Create a section

After selecting the join point, you can create the section. The cut points, notifications, and so on are defined in the section. We use the @Aspect annotation in the Spring framework to define a section class as follows:

@Aspect
public class AnnotationAspect {
    // Define the pointcut
    // Define the notification
}
Copy the code

Define the tangent point

Now that we have created the aspect class, we need to define the pointcut. As mentioned earlier, a pointcut can be viewed as a set of join points that define a range and are typically defined using regular expressions. For example, if we defined the printRole method above as a pointcut, we could write it like this:

@Pointcut("execution(* com.codergeshu.aop.service.impl.RoleServiceImpl.printRole(..) ))");
Copy the code

Analyze this expression in turn.

  • @Pointcut: defines a pointcut that decorates a method.
  • execution: indicates that this event is triggered when the method is executed.
  • *: represents a method of any return type.
  • com.codergeshu.aop.service.impl.RoleServiceImpl: represents the fully qualified name of the class.
  • printRole: Name of the intercepted method.
  • (..)Intercepted methods can have arbitrary arguments.

With the above pointcut definition, it will weave the printRole method methods into the process according to the rules of the AOP advice.

@Aspect
public class AnnotationAspect {
    // Define the pointcut
    @Pointcut("execution(* com.codergeshu.aop.service.impl.RoleServiceImpl.printRole(..) ))") public void print() {}Copy the code

4 Creating enhanced Notification

The notification type is also described above, so let’s get straight to its definition in the aspect class.

@Aspect
public class AnnotationAspect {
    // Define the pointcut
    @Pointcut("execution(* com.codergeshu.aop.service.impl.RoleServiceImpl.printRole(..) ))") public void print() {}print()") public void before() { System.out.println("before ...."); } @After("print()") public void after() { System.out.println("after ...."); } @AfterReturning("print()") public void afterReturning() { System.out.println("afterReturning ...."); } @AfterThrowing("print()") public void afterThrowing() { System.out.println("afterThrowing ...."); } // Set the ProceedingJoinPoint (@around ("print()") public Object around(ProceedingJoinPoint jp) { System.out.println("around before ...."); try { jp.proceed(); } catch (e) {e.printstackTrace ();} catch (e) {e.printstackTrace (); } System.out.println("around after ...."); return null; }}Copy the code

In the wrap notification in the code, you can see the parameter ProceedingJoinPoint, which is a class that comes with the framework and can be used to reflect join point methods.

Configure and enable Spring framework AOP

The above aspects have been defined, but if you want to use AOP in Spring projects, you need to configure enabling. As with any configuration, there are two ways: annotation-based or XML file-based. Annotation-based approach is used here:

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.codergeshu.aop")
public class AopConfig {
	@Bean
    public AnnotationAspect getRoleAspect(a) {
        return newAnnotationAspect(); }}Copy the code

@enableAspectJAutoProxy Indicates that automatic proxy of the AspectJ framework is enabled. And in this configuration class we also define our aspect class AnnotationAspect to be managed in the IOC container.

Of course, if you use XML files to enable AOP configuration is also easy, just add AOP namespace in XML file: < AOP: Aspectj-autoproxy />.

Land test and results

To test the ABOVE AOP process, we write the following test class:

@Test
public  void testAnnotation(a) {
	ApplicationContext ioc = new AnnotationConfigApplicationContext(AopConfig.class);
	Role role = new Role();
	role.setId(1L);
	role.setRoleName("CoderGeshu");
	role.setNote("I am CoderGeshu");
	// Get the dynamic proxy object and hang it in the RoleService interface
	RoleService roleService = ioc.getBean(RoleService.class);
	roleService.printRole(role);
}
Copy the code

Test results:

before ....
around before ....
{id: 1, role_name : CoderGeshu, note : I am CoderGeshu}
around after ....
after ....
afterReturning ....
Copy the code

From the test results, combined with the introduction of each of the above, you can better understand the usefulness of AOP advice.


conclusion

This article starts with what AOP is, describes what AOP does in straightforward language, then goes on to explain how it works and related terminology concepts, and finally uses a small demo to demonstrate the flow of using AOP in the Spring framework.

This article is more suitable for the students who just enter the study, I am also in the preliminary study, if there is an incorrect place, I hope you don’t hesitate to correct.

Shoulders of giants

Java EE Internet Lightweight Framework Integration development, Yang Kaizhen et al

Blog.csdn.net/qq_41981107…


The author information

Hi, I’m CoderGeshu, a programmer who loves life. Please give me a thumbs up if this article is helpful to you: 👍👍👍

In addition, welcome to pay attention to my public account of the same name: CoderGeshu, a public account dedicated to sharing programming technology knowledge!!

One person can go fast, while a group of people can go far…