This is the 25th day of my participation in Gwen Challenge

Introduction to AOP (Aspect Oriented Programming)

  1. The principle of

    1. Normal program execution flow is vertical execution flow
    2. In the original vertical execution process of the program, the process of adding a notice for a certain method or some methods to form a cross section is called cross section programming
  2. Commonly used concept

  3. Two implementations of AOP

    1. Schema-based
      • Each notification needs to implement an interface or class
      • Configure the Spring configuration file in AOP :config
    2. AspectJ
      • Each notification does not need to implement an interface or class
      • Configuring the Spring configuration file is configured in aop: Aspect, a child of AOP: Config

Schema-based

1. Pre-notification

  1. Write a pre-notification class
    1. Implement the MethodBeforeAdvice interface
    2. Before method parameter
      • Arg0: pointcut Method object Method object
      • Arg1: pointcut method parameter
      • Arg2: Which object is the pointcut in
public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method arg0, Object[] arg1, Objectarg2) throws Throwable {
        System.out.println("Pre-execution notification"); }}Copy the code

Second, post notice

  1. Write a post-notification class
    1. Implement the AfterReturningAdvice interface
    2. AfterReturning method parameters
      • Object arg0: the return value of the pointcut method
      • Method arg1: Pointcut Method object
      • Object[] arg2: pointcut method parameter
      • Object arg3: The Object of the class of the pointcut method
public class MyAfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object arg0, Method arg1,Object[] arg2, Object arg3) throws Throwable {
        System.out.println("Execute post-notification"); }}Copy the code

Three, the realization of pre-notification and post-notification

  1. Spring configuration file
    1. Tangent point: is a method
      • expression="execution(*com.bjsxt.test.Demo.demo2())"
      • * Wildcard, matches any method name, any class name, any level package name
      • If you want to match any method argument (..)
      • Ex. :com.bjsxt.test.*.demo2(..) )
        • The demo1 method (which can have arbitrary arguments) representing all classes under the com.bjsxt.test package is used as the pointcut

      
<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/sc
hema/beans
http://www.springframework.org/schema/beans/spring-be
ans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.
xsd">
    <! -- Configure the notification class object and introduce it in the section -->
    <bean id="mybefore" class="com.bjsxt.advice.MyBeforeAdvice"></bean>
    <bean id="myafter" class="com.bjsxt.advice.MyAfterAdvice"></bean>
   
    <! -- Configuration section -->
    <aop:config>
        <! -- Config pointcut -->
        <aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo2())" id="mypoint"/>
        <! -- notice -- -- >
        <aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
        <aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/>
    </aop:config>
    <! -- Configure the Demo class, test using -->
    <bean id="demo" class="com.bjsxt.test.Demo"></bean></beans>
Copy the code
  1. The 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(); }}Copy the code
  1. The results

3. Abnormal notification

  1. Inform the class
    • Inherits the ThrowsAdvice interface
    • Write your own method, which must be named afterThrowing
    • Method parameters must be 4 or 1
public class MyThrow implements ThrowsAdvice{
    // public void afterThrowing(Method m, Object[] args,Object target, Exception ex) {
        // system.out. println(" execute exception notification ");
    // }
    public void afterThrowing(Exception ex) throws Throwable {
        System.out.println("Execute exception through -schema-base mode"); }}Copy the code
  1. Spring configuration file
<bean id="mythrow" class="com.bjsxt.advice.MyThrow"></bean>
    <aop:config>
    <aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1())" id="mypoint"/>
    <aop:advisor advice-ref="mythrow" pointcut-ref="mypoint" />
    </aop:config>
<bean id="demo" class="com.bjsxt.test.Demo"></bean>
Copy the code

4. Surround notification

  1. Inform the class
    • Write both the pre-notification and the post-notification into one notification to form the surround notification
public class MyArround implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
        System.out.println("Surround-front");
        Object result = arg0.proceed();System.out.println(" wrap - back ");
        returnresult; }}Copy the code
  1. Spring configuration file
<bean id="myarround" class="com.bjsxt.advice.MyArround"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="myarround" pointcut-ref="mypoint" />
</aop:config>
<bean id="demo" class="com.bjsxt.test.Demo"></bean>
Copy the code

AspectJ

1. Exception notification

  1. Inform the class
    • Create a new class and write a method in the class with any name
public class MyThrowAdvice{
    public void myexception(Exception e1){
        System.out.println("Execute exception notification"+e1.getMessage()); }}Copy the code
  1. Spring configuration file
    • Aop: The ref attribute of an aspect indicates which class the method is in.
    • What advice does < AOP: XXXX /> represent
    • Method: Which method to call when this notification is triggered
    • Throwing: The name of the exception object, which must be the same as the method parameter name in the notification (yes

To not declare exception objects in the notification)

<bean id="mythrow" class="com.bjsxt.advice.MyThrowAdvice"></bean>
<aop:config>
    <aop:aspect ref="mythrow">
    <aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1())" id="mypoint"/>
    <aop:after-throwing method="myexception" pointcut-ref="mypoint" throwing="e1"/></aop:aspect>
</aop:config>
<bean id="demo" class="com.bjsxt.test.Demo"></bean>
Copy the code

Two, surround notification

  1. Inform the class
public class MyAdvice {
    public void mybefore(String name1,int age1){
        System.out.println("Front"+name1 );
    } 
    public void mybefore1(String name1){
        System.out.println("Front."+name1);
    } 
    public void myaftering(a){
        System.out.println("Rear 2");
    } 
    public void myafter(a){
        System.out.println(Rear "1");
    } 
    public void mythrow(a){
        System.out.println("Abnormal");
    } 
    public Object myarround(ProceedingJoinPoint p) throws
    Throwable{
        System.out.println("Execution surround");
        System.out.println("Surround-front");
        Object result = p.proceed();
        System.out.println("Surround back");
        returnresult; }}Copy the code
  1. Spring configuration file
    • Aop :after/ post notification, execute whether or not an exception occurs
    • Aop :after-returing/ post-notification, executed only if the pointcut executes correctly
    • Aop :after/ aop:after-returing/ AOP :after-throwing/ aop:after-throwing/ execution order and configuration order
    • Execution () parentheses cannot be expanded to args
    • Spring resolves “and” to “&&” instead of “&”
    • Args (Name) Name User-defined. The sequence corresponds to demo1(parameters, parameters)
    • Aop :before/ arg-names= “names” are derived from expression= “args()”, names must be the same
    • Args () has several parameters, and arg-names must have several parameters
    • The name in arg-names= must correspond to the notification method parameter name
<aop:config>
    <aop:aspect ref="myadvice">
        <aop:pointcut expression="execution(* com.bjsxt.test.Demo.demo1(String,int)) and args(name1,age1)" id="mypoint"/>
        <aop:pointcut expression="execution(* com.bjsxt.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>
Copy the code

Setting up AOP with annotations (Aspect-based)(back top)

  1. The premise
    • Spring does not automatically look for annotations and must tell spring which classes under the package might have annotations
    • Set in the Spring configuration file
<context:component-scan
base-package="com.bjsxt.advice">
</context:component-scan>
Copy the code
  1. The test class
    1. @Component
      • The equivalent of
      • If there is no argument, write the first letter of the class name smaller, equal to
      • @Component(” Custom name “)
    2. @Pointcut("execution(*com.bjsxt.test.Demo.demo1())")
      • Define the point of tangency
@Component
public class Demo {
    @Pointcut("execution(* com.bjsxt.test.Demo.demo1())")
    public void demo1(a) throws Exception{
        // int i = 5/0;
        System.out.println("demo1"); }}Copy the code
  1. Notify the category
    1. @Aspect
      • Equivalent to AOP :aspect/ denotes the notification method in the current class
@Component
@Aspect
public class MyAdvice {
    @Before("com.bjsxt.test.Demo.demo1()")
    public void mybefore(a){
        System.out.println("Front");
    } 
    @After("com.bjsxt.test.Demo.demo1()")
    public void myafter(a){
        System.out.println("Post notification");
    } 
    @AfterThrowing("com.bjsxt.test.Demo.demo1()")
    public void mythrow(a){
        System.out.println("Exception notification");
    } 
    @Around("com.bjsxt.test.Demo.demo1()")
    public Object myarround(ProceedingJoinPoint p) throws Throwable{
        System.out.println("Surround-front"); Object result = p.proceed(); System.out.println("Surround-rear");
        returnresult; }}Copy the code