[Spring] AOP development-weaving configuration

Related terms

Target

Proxy (Proxy Object)

Advice (notification/enhancement)

Joinpoint (connection point): a method that can be enhanced is called a connection point

Pointcut (pointcut): the method that is actually enhanced is called the pointcut

Aspect: point of contact + notification

Weaving (weaving): the process of combining pointcut + notification to generate agent

 
 

Development issues

▍What needs to be written/configured?

  • Write the target class and target method
  • Write aspect classes and enhancement methods
  • Configure the weaving relationship and tell Spring which pointcuts are combined with which notifications

Please briefly SpringAOP the process?

  1. Spring will automatically monitor the execution of pointcut methods
  2. Once the pointcut method is executed, the proxy mechanism is immediately triggered, that is, the proxy object of the target object where the target method is dynamically created
  3. The method of notifying the corresponding position of the woven into the proxy object, composing the complete code logic and running

What kind of dynamic proxy mode will be used at the bottom of AOP?

  • Spring will automatically decide which dynamic proxy method to use (JDK/cglib) according to whether the target class implements the interface

▍What maven coordinates need to be imported?

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>5.0.5.RELEASE</version>
</dependency>
<dependency>
     <groupId>org.aspectj</groupId>
     <artifactId>aspectjweaver</artifactId>
     <version>1.8.4</version>
</dependency>

<!-- spring拥有自己的aop包,但实际上使用的是更加优秀的aspectj提供的aop包 -->

 
 

Based on XML (code)

① Write the target class and target method

目标类接口 ----------------------------------------------------------------------------------
public interface TargetInterface {
    
    
    public void sayHi();
}


目标类 -------------------------------------------------------------------------------------
public class Target implements TargetInterface {
    
    

    public void sayHi() {
    
    
        System.out.println("Hello >_<!");
    }
}

② Compile aspect classes and enhancement methods

切面类 -------------------------------------------------------------------------------------
public class MyAspect {
    
    

    public void enhanceBefore() {
    
    
        System.out.println("前置增强...");
    }

    public void enhanceAfterReturning() {
    
    
        System.out.println("后置增强...");
    }

    public Object enhanceAround(ProceedingJoinPoint joinPoint) throws Throwable {
    
    
        System.out.println("环绕前增强...");
        Object obj = joinPoint.proceed();
        System.out.println("环绕后增强...");
        return obj;
    }

    public void enhanceAfterThrowing() {
    
    
        System.out.println("异常抛出增强...");
    }

    public void anhanceAfter() {
    
    
        System.out.println("最终增强...");
    }

}

③ Configuration file (introduce the aop namespace, put the object into the container, and tell Spring to weave the relationship)

<?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="target" class="aop.Target"></bean>

    <!-- 切面对象 -->
    <bean id="aspect" class="aop.MyAspect"></bean>

    <!-- 配置织入关系 -->
    <aop:config>
        <!-- 声明切面 (切面=切点+通知) -->
        <aop:aspect ref="aspect">
            <aop:before method="enhanceBefore" pointcut="execution(public void aop.Target.sayHi())" />
            <aop:after-returning method="enhanceAfterReturning" pointcut="execution(public void aop.Target.sayHi())" />
            <aop:around method="enhanceAround" pointcut="execution(public void aop.Target.sayHi())" />
            <aop:after-throwing method="enhanceAfterThrowing" pointcut="execution(public void aop.Target.sayHi())" />
            <aop:after method="anhanceAfter" pointcut="execution(public void aop.Target.sayHi())" />
        </aop:aspect>
    </aop:config>


</beans>

④ Turn on component scanning and AOP automatic proxy ( it's easy to forget >_< )

<!-- 开启组件扫描 -->
<context:component-scan base-package="XXX" />

<!-- AOP自动代理 -->
<aop:aspectj-autoproxy />

⑤ Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    
    

    @Autowired
    private TargetInterface target;

    @Test
    public void test1() {
    
    
        target.sayHi();
    }

}

Insert picture description here

 
 

Based on XML (detailed explanation)

1) Cut point expression

格式:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))

细节:
1. 访问修饰符(public/private)可以省略
2. 在任意位置可使用通配符(*)
3. 单点(.)表示当前包下的所有类,双点(..)表示当前包及其子包下的所有类
4. 参数使用双点(..)表示任意参数

示例:
execution(public void com.samarua.dao.UserDaoImpl.addUser(int))	
// 匹配UserDaoImpl类中的公共的、返回为空的、参数为int的、UserDaoImpl类的addUser方法

execution( * com.samarua.dao.UserDaoImpl.*(..))	
// 匹配UserDaoImpl类中的所有方法

execution(* com.samarua.dao..*.*())	
// 匹配dao包及其子包下的所有类的所有无参的方法

2) Type of notification

Advance notice before
Post notification after-returning
Surround notification around
Exception thrown notification after-throwing
Final notice after

3) Extraction of cut-point expression

<!-- 就是给一个切点表达式起一个名字,配合使用pointcut-ref,从而避免反复写相同的表达式 -->

<aop:config>
    <aop:aspect ref="aspect">
        <aop:pointcut id="myPiontcut" expression="execution(public void aop.Target.sayHi())"/>
        <aop:before method="enhanceBefore" pointcut-ref="myPiontcut" />
        <aop:after-returning method="enhanceAfterReturning" pointcut-ref="myPiontcut" />
        <aop:around method="enhanceAround" pointcut-ref="myPiontcut" />
        <aop:after-throwing method="enhanceAfterThrowing" pointcut-ref="myPiontcut" />
        <aop:after method="anhanceAfter" pointcut-ref="myPiontcut" />
    </aop:aspect>
</aop:config>

 
 
 

Based on annotations (code)

① Write the target class and target method

@Component("target")			// 目标对象放入Spring容器
...

② Compile the aspect classes and enhancement methods (the configuration of the weaving relationship was carried out at the same time)

@Component("aspect")			// 切面对象放入Spring容器
@Aspect							// 告诉Spring这是一个切面类(一定不要忘记这个细节>_<!!!)
public class MyAspect {
    
    

    @Before("execution(* com.samarua.aop.*.*(..))")
    public void enhanceBefore() {
    
    
        System.out.println("前置增强...");
    }

    @AfterReturning("execution(* com.samarua.aop.*.*(..))")
    public void enhanceAfterReturning() {
    
    
        System.out.println("后置增强...");
    }

    @Around("execution(* com.samarua.aop.*.*(..))")
    public Object enhanceAround(ProceedingJoinPoint joinPoint) throws Throwable {
    
    
        System.out.println("环绕前增强...");
        Object obj = joinPoint.proceed();
        System.out.println("环绕后增强...");
        return obj;
    }

    @AfterThrowing("execution(* com.samarua.aop.*.*(..))")
    public void enhanceAfterThrowing() {
    
    
        System.out.println("异常抛出增强...");
    }

    @After("execution(* com.samarua.aop.*.*(..))")
    public void anhanceAfter() {
    
    
        System.out.println("最终增强...");
    }

}

 
 

Based on annotations (detailed explanation)

1) Cut point expression

2) Type of notification

2) Extraction of cut-point expression

@Component("aspect")
@Aspect
public class MyAspect {
    
    

	// 随便写一个空的方法作为依托,注解上切点表达式,之后直接使用该方法名即可替代表达式

    @Pointcut("execution(* anno.*.*(..))")
    public void myPointcut() {
    
    }

    @Before("myPointcut()")
    public void enhanceBefore() {
    
    
        System.out.println("前置增强...");
    }

    @AfterReturning("myPointcut()")
    public void enhanceAfterReturning() {
    
    
        System.out.println("后置增强...");
    }

}

 
 
 
 

 
 
 
 

 
 
 
 

More >_<

Guess you like

Origin blog.csdn.net/m0_46202073/article/details/113980459