Introduction to Spring Framework (2)

1. Aspect programming

Concept: In the original vertical execution process of the program, adding notifications for a certain method or methods to form a cross-section is called section-oriented programming.
Commonly used section concepts:

  • Original function: pointcut, pointcut
  • Before advice: A function executed before the point of cut. Before advice
  • After advice: a function executed after the point of cut, after advice
  • If an exception occurs during the execution of the pointcut, an exception notification will be triggered.
  • All the functions are collectively called the aspect.
  • Weaving: The process of embedding the aspect into the original function is called weaving

Two, AOP

1. AOP: Aspect Oriented Programming is also known as aspect-oriented programming.
2. Function: The normal program execution flow is a vertical execution flow, while AOP adds a cross-section to the original vertical execution flow without modifying the original program code.
3. Advantages: high scalability, the original function is equivalent to releasing part of the logic. Make the function responsibilities more clear.
Insert picture description here
4. Spring provides 2 AOP implementation methods
4.1, Schema-based

  • Every notification needs to implement an interface or class
  • When configuring the spring configuration file, configure
    4.2, AspectJ in aop:config
  • Every notification does not need to implement an interface or class
  • The spring configuration file is configured in the subtag aop:aspect of aop:config

Three, Schema-based implementation steps

1. Import Jar
(other jar packages of Spring need to be imported)
Insert picture description here
2. New notification class
2.1, new pre-notification class

  • arg0: Method object of pointcut method object
  • arg1: tangent method parameter
  • arg2: Which object is the tangent point in
public class MyBeforeAdvice implements MethodBeforeAdvice {
    
    
	@Override
	public void before(Method arg0, Object[] arg1, Objectarg2) throws Throwable {
    
    
		System.out.println("执行前置通知");
		}
}

2.2. New post notification class

  • arg0: return value of tangent method
  • arg1: Point-cut method object
  • arg2: tangent method parameter
  • arg3: The object of the class where the pointcut method is located
public class MyAfterAdvice implements AfterReturningAdvice {
    
    
	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    
    
		System.out.println("执行后置通知");
	}
}

3. Configure the spring configuration file

  • Introduce the aop namespace
  • Configure the notification class
  • Configuration aspect
  • *Wildcard, match any method name, any class name, any first-level package name
  • If you want to match any method parameters (...)
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置通知类对象,在切面中引入 -->
	<bean id="mybefore" class="com.jax.advice.MyBeforeAdvice"></bean>
	<bean id="myafter" class="com.jax.advice.MyAfterAdvice"></bean>
	<!-- 配置切面 -->
	<aop:config>
		<!-- 配置切点 -->
		<aop:pointcut expression="execution(*com.jax.test.Demo.demo2())" id="mypoint"/>
		<!-- 通知 -->
		<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
		<aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/>
	</aop:config>
	<!-- 配置 Demo 类,测试使用 -->
	<bean id="demo" class="com.jax.test.Demo"></bean>
</beans>

4. Write test code

public class Test {
    
    
	public static void main(String[] args) {
    
    
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
			Demo demo = ac.getBean("demo",Demo.class);
			demo.demo1();
			demo.demo2();
			demo.demo3();
	}
}

5. Execution results
Insert picture description here

Fourth, the steps to configure exception notification (AspectJ method)

  1. Only when the cut point reports an exception can the exception notification be triggered
  2. There is an AspectJ method in spring that provides an exception notification method.
    If you want to implement it through schema-base, you need to write your own method according to specific requirements.
  3. Implementation steps:
    3.1. Create a new class and write a method with any name in the class
public class MyThrowAdvice{
    
    
	public void myexception(Exception e1){
    
    
		System.out.println("执行异常通知"+e1.getMessage());
	}
}

3.2 Configure in the spring configuration file

  • The ref attribute of aop:aspect indicates: which class the method is in.
  • What does <aop: xxxx/> mean?
  • method: which method to call when this notification is triggered
  • throwing: The name of the exception object must be the same as the method parameter name in the notification (the exception object may not be declared in the notification)
<bean id="mythrow"class="com.jax.advice.MyThrowAdvice"></bean>
	<aop:config>
		<aop:aspect ref="mythrow">
		<aop:pointcut expression="execution(*com.jax.test.Demo.demo1())" id="mypoint"/>
		<aop:after-throwing method="myexception" pointcut-ref="mypoint" throwing="e1"/></aop:aspect>
	</aop:config>
<bean id="demo" class="com.jax.test.Demo"></bean>

5. Exception notification (Schema-based method)

1. Create a new class to implement the throwsAdvice interface

  • You must write the method yourself, and it must be called afterThrowing
  • There are two parameter modes, which must be 1 or 4
  • The exception type should be consistent with the exception type reported by the cutpoint
public class MyThrow implements ThrowsAdvice{
    
    
// public void afterThrowing(Method m, Object[] args,
Object target, Exception ex) {
    
    
// System.out.println("执行异常通知");
// }
	public void afterThrowing(Exception ex) throws
	Throwable {
    
    
		System.out.println("执行异常通过-schema-base 方式");
}
}

2. Configure in ApplicationContext.xml

	<bean id="mythrow" class="com.jax.advice.MyThrow"></bean>
	<aop:config>
		<aop:pointcut expression="execution(*com.jax.test.Demo.demo1())" id="mypoint"/>
		<aop:advisor advice-ref="mythrow" pointcut-ref="mypoint" />
	</aop:config>
	<bean id="demo" class="com.jax.test.Demo"></bean>

Sixth, surround notification (Schema-based method)

1. Write both the pre-notification and the post-notification into one notification to form a surround notification
2. Implementation steps
Create a new class to implement MethodInterceptor

public class MyArround implements MethodInterceptor {
    
    
	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
    
    
		System.out.println("环绕-前置");
		Object result = arg0.proceed();//放行,调用切点方式
		System.out.println("环绕-后置");
		return result;
	}
}

Configure application.xml

	<bean id="myarround" class="com.jax.advice.MyArround"></bean>
	<aop:config>
		<aop:pointcut expression="execution( *com.jax.test.Demo.demo1())" id="mypoint"/>
		<aop:advisor advice-ref="myarround" pointcut-ref="mypoint" />
	</aop:config>
	<bean id="demo" class="com.jax.test.Demo"></bean>

Seven, use AspectJ

1. Create a new class, do not need to implement
1.1, the method name in the class is arbitrary

public class MyAdvice {
    
    
public void mybefore(String name1,int age1){
    
    
	System.out.println("前置"+name1 );
}
public void mybefore1(String name1){
    
    
	System.out.println("前置:"+name1);
}
public void myaftering(){
    
    
	System.out.println("后置 2");
}
public void myafter(){
    
    
	System.out.println("后置 1");
}
public void mythrow(){
    
    
	System.out.println("异常");
}
public Object myarround(ProceedingJoinPoint p) throws Throwable{
    
    
	System.out.println("执行环绕");
	System.out.println("环绕-前置");
	Object result = p.proceed();
	System.out.println("环绕后置");
	return result;
}
}

1.2, configure spring configuration file

  • aop:after/ post notification, whether there is an exception, it will be executed
  • aop:after-returing/ post notification, only executed when the cut point is executed correctly
  • aop:after/ and aop:after-returing/ and aop:after-throwing/ execution order is related to configuration order
  • execution() brackets cannot be expanded with args
  • Use and in the middle and cannot use &&. Spring will parse and into &&
  • args (name) name custom. The order corresponds to demo1 (parameters, parameters)
  • aop:before/ arg-names=” name” The name comes from
    args() in expression=”” , the name must be the same, args() has several parameters, arg-names must have several parameters, arg-names=” "The
    name inside must correspond to the parameter name of the notification method
<aop:config>
<aop:aspect ref="myadvice">
<aop:pointcut expression="execution(*com.jax.test.Demo.demo1(String,int)) and args(name1,age1)" id="mypoint"/>
<aop:pointcut expression="execution(*com.jax.test.Demo.demo1(String)) and args(name1)" id="mypoint1"/>
<aop:before method="mybefore" pointcut-ref="mypoint" arg-names="name1,age1"/>
<aop:before method="mybefore1" pointcut-ref="mypoint1" arg-names="name1"/>
<!-- <aop:after method="myafter"
pointcut-ref="mypoint"/>
<aop:after-returning method="myaftering"
pointcut-ref="mypoint"/>
<aop:after-throwing method="mythrow"
pointcut-ref="mypoint"/>
<aop:around method="myarround"
pointcut-ref="mypoint"/>-->
</aop:aspect>
</aop:config>

8. Use annotations (based on Aspect)
1. Spring will not automatically look for annotations. You must tell spring which packages under the class may have annotations
1.1 Introduce xmlns:context

<context:component-scan base-package="com.jax.advice"></context:component-scan>

2、@Component

  • Equivalent to
  • If there are no parameters, change the first letter of the class name to lowercase, which is equivalent to
  • @Component("Custom Name")

3. Implementation steps:

3.1. Set the annotations in which packages in the spring configuration file

<context:component-scanbase-package="com.jax.advice,com.jax.test"></context:component-scan>

3.2. Add @Componet to the Demo class and add
@Pointcut(“”) to the method to define the cut point

@Component
public class Demo {
    
    
@Pointcut("execution(*com.jax.test.Demo.demo1())")
public void demo1() throws Exception{
    
    
// int i = 5/0;
	System.out.println("demo1");
}
}

3.3 Configure in the notification class

  • @Component class is managed by spring
  • @Aspect is equivalent to aop:aspect/ indicates that the notification method is in the current class
@Component
@Aspect
public class MyAdvice {
    
    
@Before("com.jax.test.Demo.demo1()")
public void mybefore(){
    
    
	System.out.println("前置");
}
@After("com.jax.test.Demo.demo1()")
public void myafter(){
    
    
	System.out.println("后置通知");
}
@AfterThrowing("com.jax.test.Demo.demo1()")
public void mythrow(){
    
    
	System.out.println("异常通知");
}
@Around("com.jax.test.Demo.demo1()")
public Object myarround(ProceedingJoinPoint p) throws Throwable{
    
    
	System.out.println("环绕-前置");
	Object result = p.proceed();
	System.out.println("环绕-后置");
	return result;
}
}

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_45323996/article/details/115110929