Spring中AOP注解实现

100 阅读1分钟

文章目录

AOP的一些名词

连接点:类中可以被增强的方法
切入点:类中实际被增强的方法
通知:实际增强方法的部分
切面:把通知应用到切入点的过程
其中通知常用的有前置通知,后置通知,环绕通知

AOP具体实现

Spring AOP是基于AspectJ实现的,所以需要先引入依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

这里我们通过注解来实现,所以开启注解,然后开启注解扫描的包,同时开启Aseptic生成代理对象

<!--    开启注解支持-->
<context:annotation-config/>
<!--    配置要扫描的包下的注解生效-->
<context:component-scan base-package="com.hzy.aopanno"/>
<!--    开启Aspect生成代理对象-->
<aop:aspectj-autoproxy/>

准备工作做的差不多了,可以开始应用了,如果我们要对User类下的add方法加一个前置通知,也就是执行该方法前执行的操作,首先创建一个User类,并把该类注入到Spring

package com.hzy.aopanno;

import org.springframework.stereotype.Component;

@Component
public class User {
    public void add() {
        System.out.println("add ...");
    }
}

然后是一个User的代理类,也就是负责通知的,这里的@Aspect就是切面,把该通知应用到切入点,其中execution(* com.hzy.aopanno.User.add(..))代表对add方法进行切入,如果所有的方法切人是execution(* com.hzy.aopanno.User.*(..))

package com.hzy.aopanno;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class UserProxy {
    @Before(value = "execution(* com.hzy.aopanno.User.add(..))")
    public void before() {
        System.out.println("before ...");
    }
}

下面我们测试一下

import com.hzy.aopanno.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }
}

在这里插入图片描述
然后我们再进行演示after和around
修改代理类

package com.hzy.aopanno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class UserProxy {
    @Before(value = "execution(* com.hzy.aopanno.User.add(..))")
    public void before() {
        System.out.println("before ...");
    }

    @After(value = "execution(* com.hzy.aopanno.User.add(..))")
    public void after() {
        System.out.println("after ...");
    }

    @Around(value = "execution(* com.hzy.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前 ...");
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后 ...");

    }
}

观察测试结果会发现,在before之前会环绕,after之前也会环绕
在这里插入图片描述