Spring Learning Records (5) - Preliminary Experience of AOP

2018.4.16

Please correct me for my own lack of understanding~

What is AOP?

The following examples refer to KenWang's blog~

AOP (Aspect Oriented Programming) - Aspect Oriented Programming

AOP and IoC are one of the two core ideas of Spring

It is also a supplement to traditional OOP (Object Oriented Programming)

In OOP, various vertical relationships in real life can be imitated by concepts such as inheritance and polymorphic encapsulation

But OOP doesn't work for mimicking horizontal relationships

What is a horizontal relationship?

Imagine a few real life examples:

1. When operating the ATM, we may perform the following operations:

  •    Withdrawal: start - enter password - withdraw - end
  •    Transfer: start - enter password - transfer - end
  •    Balance: start - enter password - query - end

In this example we can see that if we take the withdrawal and transfer to query the balance as the core operation

Then the operation of entering the password is the " auxiliary operation " called by the core operation

This description does not mean that the importance of auxiliary operations is low, but relative to the core operations of each specialization

Secondary actions appear repetitive and irrelevant

2. The following operations may be required in a shopping system:

  • Provide transaction management for each order generated
  • When a user clicks or searches for a certain keyword, we want to count the click-through rate of this type of product
  • When users log in, log out, and change their passwords, we need to record the location and time of the operation.

All three operations in this example can be thought of as " auxiliaries " to the core business function

How do you understand this with "aspect" and "horizontal relationship"?



We can see that in the ATM example, we draw three straight lines for three unrelated businesses of withdrawal, transfer, and balance inquiry.

And these three services all require the support of the auxiliary function of entering a password

And this red line that cuts into the three black lines is the so-called " cut plane "

The intersection of the red and black lines can be called the " point of tangent "

Also established a " horizontal relationship "

In the idea of ​​aspect-oriented programming AOP

Let core business functions and aspect functions be developed independently

And then weaving the two together is called AOP



Why use AOP?

Like IoC, another core idea of ​​Spring, AOP is also committed to making the code more concise and clear, let us spend more time on the construction of the core code

If in the ATM example

Withdrawal, transfer and balance inquiry are three different services

Now all three services require the support of the "authentication" feature

So what to do?

Maybe you will think of adding a piece of authentication code to these three pieces of code

Maybe you think about writing a separate function and calling it when the three services start

But these methods will produce code duplication and coupling

In summary:

AOP can make business modules more concise and solve the problem of coupling between business logic and auxiliary modules


Getting started with AOP

Additional packages added:


Other Spring required packages are the same as before


We use such an example:

Now there is a login service we need to print the system time before and after login

We take login service as core business and print time as ancillary business

First build the project structure:


Write the Timeprint class in the aspect package:

package com.tzy.aspect;

public class Timeprint
{
	public void printTime ()
	{
		System.out.println("The current time is: "+System.currentTimeMillis());
	}
}

Write the Login class in the serve package:

package com.tzy.serive;

import java.util.Scanner;

public class Login
{
	public void log()
	{
		Scanner sc=new Scanner(System.in);
		System.out.println("Please enter user name:");
		String username=sc.next();
		System.out.println(username+"Login successful!");
	}
}

Write the test class:

package com.tzy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tzy.serive.Login;

public class testAOP
{
	public static void main(String args[])
	{
		ApplicationContext context=new ClassPathXmlApplicationContext
				(new String[]{"applicationContext.xml"});
		Login user1=(Login)context.getBean("login");
		user1.log();
	}
}

Now configure the applicationContext:

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context      
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
   <context:annotation-config/>
      
   <bean name="login" class="com.tzy.serive.Login" >
   </bean>
    <bean id="Timeprint" class="com.tzy.aspect.Timeprint">
   </bean>
   
   <aop:config>
   		<aop:aspect id="time" ref="Timeprint">
   				<aop:pointcut id="test1"
   				expression="execution(* com.tzy.serive.Login.*(..))"/>
   				<aop:before method="printTime" pointcut-ref="test1"/>
   				<aop:after method="printTime" pointcut-ref="test1"/>
   		</aop:aspect>
   </aop:config>
	
  </beans>

run:



Next, explain some of the problems in the configuration file

1. Please refer to the previous article for the assembly of the bean class


2.<aop:aspect>


Use the ref attribute directly when the aspect code is an auto-injected bean

Above we can see the injection to the Timerprint class:



3.<aop:pointcut>与execution

pointcut means to create a pointcut

execution is more complicated

Here first use execution(* *.*(..)) instead

The first occurrence of * means: matching any return type method can be changed to void int double to match a specific return type function

The second occurrence of * means: full class name

The third occurrence of * means: match any method name

The last occurrence of (..) means: match any type and number of parameters 


4. <aop before> and others

We need to configure when to execute the aspect code, such as before or after the core business call

There are the following types:


  • after invokes the notification after the method completes regardless of whether it succeeded or not
  • after-returning is called after the method has successfully executed
  • after-throwing is called after a method throws an exception
  • around is called before and after
  • before calls the notification before the method call

5.method


As shown in the figure, we called the printTime method in the previous tests, which is a method in the aspect class.

Now we add a method to the aspect class:


At this point, modify the method to:


Run the test class:


You can see that the notification function called is different


Summarize:

The above is the simple usage of AOP

The use of annotations for AOP operations will be supplemented in the future.

Another thing to note is that Spring only supports method join points and pointcuts can only be constructed when a method is called


Thank you~

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324469800&siteId=291194637