Detailed explanation of Spring AOP framework based on XML configuration

Keywords: Java Spring xml AOP

Learning AOP in Spring is to realize relevant interception and cut in functions through configuration (XML based configuration and annotation based configuration). Strengthen the original operation, but do not affect the original operation.

catalogue

Learning AOP in Spring is to realize relevant interception and cut in functions through configuration (XML based configuration and annotation based configuration). Strengthen the original operation, but do not affect the original operation.

1. Understanding: This is the case with Aop's enhancement. You just want to query users, but I'll expand your process during your process. (Xiaobian's personal understanding)

​   2. Required jar packages

3. Learning can be roughly divided into two categories

4.xml environment configuration

5.main function call

6.IUserService interface

7.IUserService interface implementation class

8. Weave in the file MyLogger

9.aop configuration explanation:

10. Pointcut expression (*)

1. Understanding: This is the case with Aop's enhancement. You just want to query users, but I'll expand your process during your process. (Xiaobian's personal understanding)

  2. Required jar packages

3. Learning can be roughly divided into two categories

(1) Pre, post, exception, final

  •   Pre notification: executed before the pointcut method is executed
  • Post notification: executed after the pointcut method executes normally. It and exception notification can always be executed only once
  • Exception notification: executed after an exception is generated during pointcut method execution. It and post notification can always execute only one
  • Final notification: the pointcut method executes after it whether it executes normally or not

(2) Surround

  • Previously, when to execute the enhanced code was specified by configuration, but now it is specified by code control.
  • Therefore, surround notification is a way provided by the Spring framework to manually control when the enhanced method is executed in the code.

4.xml environment configuration

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/aop
	   https://www.springframework.org/schema/aop/spring-aop.xsd">

	<bean id="userServiceImpl"
		class="com.bookmanagesystem.service.impl.UserServiceImpl"></bean>
	<bean id="mylogger"
		class="com.bookmanagesystem.util.MyLogger">


	</bean>
	<aop:config>
		<aop:pointcut
			expression="execution(* com.iflytek.bookmanagesystem.service.impl.*.*(..) )"
			id="pc1" />
		<!-- 3. Configure section -->
		<aop:aspect id="logAdvice" ref="mylogger">
			<!-- Configure the type of notification (original method) -->
			<!-- <aop:before method="printLog" pointcut-ref="pc1" /> <aop:after-returning method="printLog" pointcut-ref="pc1" /> -->

			<!-- <aop:before method="printLog" pointcut="execution(public void com.bookmanagesystem.service.impl.UserServiceImpl.delete() 
				)" /> -->
			<!-- 1. Configure pre notification -->
			<!-- <aop:before method="beforePrintLog" pointcut-ref="pc1" /> -->
			<!-- 2. Configure post notification -->
			<!-- <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pc1" 
				/> -->
			<!-- 3. Configure exception notification -->
			<!-- <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pc1" 
				/> -->
			<!-- 4. Configure final notification -->
			<!-- <aop:after method="afterPrintLog" pointcut-ref="pc1" /> -->
			<!-- 5. Configure surround notifications -->
			<aop:around method="aroundPrintLog" pointcut-ref="pc1" />
		</aop:aspect>
	</aop:config>

</beans>

5.main function call

public static void main(String[] args) {
        // 1. Get the core container object
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 2. Get the bean object according to the id
        IUserService service = (IUserService) context.getBean("userServiceImpl");
        service.update();

        // 3. Close the container (if you don't remember to close the container, the most typical problem is that the database connection cannot be released)
        ((ClassPathXmlApplicationContext) context).close();
    }

6.IUserService interface

public interface IUserService {
	
    void update();
    // Simulate update user action
}

7.IUserService interface implementation class

public class UserServiceImpl implements IUserService {
       //Simulated
	@Override
	public void update() {
        System.out.println("Modify the user's operation");
	}

}

8. Weave in the file MyLogger

public class MyLogger {
	/**
	 * It is used to print the log and let it execute before the execution of the pointcut method (the pointcut method is the business method)
	 */

	// Before advice 
	public void beforePrintLog() {
		System.out.println("Before advice  MyLogger Class beforePrintLog Method starts logging...");
	}

	// Post notification
	public void afterReturningPrintLog() {
		System.out.println("Post notification MyLogger Class afterReturningPrintLog Method starts logging...");
	}

	// Exception notification
	public void afterThrowingPrintLog() {
		System.out.println("Exception notification MyLogger Class afterThrowingPrintLog Method starts logging...");
	}

	// Final notice
	public void afterPrintLog() {
		System.out.println("Final notice MyLogger Class afterPrintLog Method starts logging...");
	}
	//Around Advice 
	public Object aroundPrintLog(ProceedingJoinPoint pjp) {
	Object result = null;
	try {
	Object[] args = pjp.getArgs(); // Get the parameters required for method execution
	System.out.println("Surround notification logging");
	result = pjp.proceed(args); // Explicitly invoke business layer methods (pointcut methods)
	System.out.println("Surround notification log post");
	return result;
	} catch (Throwable e) { // The processed method throws Throwable, which can't be stopped with Exception here
	System.out.println("Circular notification logging exception");
	e.printStackTrace();
	throw new RuntimeException(e);
	} finally {
	System.out.println("Final notification record date");
	} }
}

9.aop configuration explanation:

1. Leave the notification Bean to Spring for management
• 2. Use aop:config The tag indicates the start of AOP configuration
• 3. Use aop:aspect The label indicates the configuration section
– Properties:
» id: provide a unique identification for the section
» ref : Specifies the id of the notification class bean
• 4. In aop:aspect The corresponding tag is used inside the tag to configure the type of notification
– For example, now you want the pringLog method to execute before the pointcut method is executed, so it is a pre notification
– label: aop:before In addition, there are other notification type tags
– Properties:
» method : specifies which method in the Logger class is pre notification
XML based AOP configuration steps in Spring
• Continue in aop:before Add an attribute to the tag: pointcut Pointcut properties that specify a
individual Pointcut expression , which methods in the business layer should be enhanced.
• Pointcut expression: Execution (expression) , where
– expression: Access modifier return value package name. Package name... Class name. Method name (parameter list)
– Standard expression: public void com.bookmanagesystem.service.impl.UserServiceImpl.update()

< Aop: config > / / indicates that I have started configuring Aop
        <aop:pointcut expression="execution(* com.bookmanagesystem.service.impl.*.*(..) )"
             Id = "pc1" / > / / 1. A simple way to write it can also be written as the specific above. 2. I named "pc1" for all the methods under my bookmanagesystem.service.impl.UserServiceImpl. Package
        <!-- 3. Configuration section -- >
        < AOP: aspect id = "logadvice" ref = "mylogger" > / / ref let me link my aspect with the woven file for enhancement
            < AOP: around method = "around printlog" pointcut ref = "pc1" / > / / the surrounding method is the public object around printlog (proceedingjoinpoint PJP) {} method in my MyLogger class, because pc1 contains all the methods I wrote under the package com.bookmanagesystem.service.impl
        </aop:aspect>
    </aop:config>

• Although the pointcut expression is now streamlined, you still need to configure multiple types of notifications later
To configure one for different notification types pointcut Property, you have to write a pointcut expression once, all of which are
Is it a duplicate content or needs to be further optimized to extract the pointcut expression.
• Through label <aop:pointcut> To configure the pointcut expression, and then make the
Use one of them pointcut-ref Property to specify the configured pointcut expression:
– label: <aop:pointcut />
– Properties:
» id : Specifies the unique identity of the expression
» expression : Specifies the content of the expression
– Writing position: in <aop:config> Internal, and note:
» If this label is written in < AOP: aspect > inside tag , can only be used in the current slice
» If written in Inside the < AOP: config > and outside the < AOP: aspect > tag , then all sections can make
Use, but note that the constraint must appear in front of the < AOP: aspect > tag

10. Pointcut expression (*)

Generic writing method of pointcut expression (summary: everything can be represented by (*) and parameters by (..))
  Standard writing: public int
com.bookmanagesystem.service.impl.UserServiceImpl.update()
• 1. The access modifier can be omitted: int
com.bookmanagesystem.service.impl.UserServiceImpl.update()
• 2. Wildcards can be used for the return value * Represents any return value type: *
com.bookmanagesystem.service.impl.UserServiceImpl.update()
• 3. The package name can use wildcards to represent any package, but there are several levels of packages that need to write several *: *
*.*.*.*.*.UserServiceImpl.update()
• 4. It can also be used in the package name .. To represent the current package and its sub packages, so you can use *.. To represent any
Packages and sub packages: * *..UserServiceImpl.update()
• 5. Wildcards can be used for both class name and method name: * *..*.*() Note: only 2 methods can be enhanced at this time,
Because the second method has parameters
• 6. About parameters:
– Data types for which parameters can be written directly:
» Write the name of the basic type directly, such as: *.. *. * (int)
» Write the fully qualified name of the reference type, such as: *.. *. * (java.lang.String)
– Wildcards can be used to represent any parameter type, but there must be parameters: * *. *. * (*)
– have access to .. To indicate whether there are parameters or not. If there are parameters, they can be of any type: * *. *. * (..)
• 7. All pass collocation : * *..*.*(..)
• 8. Common writing method of pointcut expression in actual development: switch to all writing methods under the business layer implementation class:
* com.bookmanagesystem.service.impl.*.*(..)

Posted by Rottingham on Wed, 10 Nov 2021 02:58:58 -0800