代码详解 AOP 概念

图片

谈到Spring,相信只要从事Java开发的同学都知道Spring的两大核心:AOP 和IOC, 本文只谈AOP。

AOP的概念,相信很多人面试都被问到过,但每次都弄的不太清楚,比如: 什么是切面,什么是增强,什么是切点...

面对如此晦涩难懂的名词,本文尝试通过代码帮助大家理解并记忆这些概念,为了便于理解,这里使用xml配置方式,实际工作中用的比较多的还是注解方式。话不多说,撸代码:


<?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="userService" class="top.lovelily.spring.service.impl.UserServiceImpl"/>
        <bean id = "helloArroundAdvice" class="top.lovelily.spring.aop.HelloAroundAdvice"/>
        <bean id ="logAspect" class="top.lovelily.spring.aop.LogAspect"/>

        <aop:config>
              <!--第一种:aspect方式配置切面-->
                <aop:aspect id="logAspect" ref="logAspect">
                        <!--execution(返回值 包名.接口名.方法名(参数)-->
                        <!--execution(User top.lovelily.spring.service.UserService.get())-->
                        <aop:pointcut id="serviceOperation"
                                      expression="execution(* top.lovelily.spring.service.*.*(..))"/>

                        <aop:around
                                pointcut-ref="serviceOperation"
                                method="doAroundLog"/>

                </aop:aspect>
                <!--第一种:aspect方式配置切面-->
                
                <!--第二种:advisor方式配置切面-->
                <aop:pointcut id="myPointcut" expression="execution(* top.lovelily.spring.service.*.*(..))"/>
                <aop:advisor advice-ref="helloArroundAdvice" pointcut-ref="myPointcut"/>
                <!--第二种:advisor方式配置切面-->
        </aop:config>
</beans>

beans.xml


public class LogAspect {
    public Object doAroundLog(ProceedingJoinPoint joinPoint) {
        System.out.println("begin...");
        try {
            Object result = joinPoint.proceed();

            // execution(void top.lovelily.spring.service.UserService.save(User))
            System.out.println(joinPoint);
            // top.lovelily.spring.service.impl.UserServiceImpl@3e3047e6
            System.out.println(joinPoint.getTarget());

            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("end...");
        return null;
    }
}

LogAspect.java


public class TestAop {
    public static void main(String[] args) {
        UserService userService1 = new UserServiceImpl();
        System.out.println(userService1 instanceof UserServiceImpl); // true
        System.out.println(userService1 instanceof UserService);    //true

        System.out.println("------------------------------------");
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
        Object bean = context.getBean("userService");
        System.out.println(bean instanceof Advised); // true

        System.out.println(bean instanceof UserService); // true
        
        UserService userService = (UserService) bean;

        User user = new User();
       // userService.save(user);
        User user1 = userService.get();
        System.out.println(user1);

    }
}

   TestAop .java

通过代码运行结果,总结AOP相关概念:

  • joinpoint:连接点,程序执行时的某个特定的点,在Spring中就是某一个方法的执行,如程序中打印的execution(User top.lovelily.spring.service.UserService.get())

  • pointcut:切点,方法的集合,包含多个joinpoint,通常会有通配符,xml配置文件中的execution(* top.lovelily.spring.service.*.*(..))

  • aspect:切面,可以横跨多个class,封装了一些操作(advice),  就是个,封装了具体要插入的操作,比如LogAspect.java记录了开始结束日志。

  • advice:通知,在切点执行的操作,before, after,aroud:具体要添加的操作(方法), 就是个方法,比如LogAspect.java中的doAroundLog方法

  • advisor:通知器,从advisor方式配置切面方式的配置中可以看出,就是pointcut和advice的适配

  • advised: 也称为目标对象,或者说被代理对象,即我们的bean


如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~

posted on 2021-07-25 14:58  XuHe1  阅读(36)  评论(0编辑  收藏  举报