• Spring——AOP(Aspect Oriented Programming)


    什么是AOP(Aspect Oriented Programming)

    AOP(Aspect Orient Programming)是面向切面编程,作为面向对象编程的一种补充,已经成为一种比较成熟的编程方式。面向切面编程将程序运行过程分解成各个切面;AOP专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在JavaEE应用中,常常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等
    AOP的核心思想是:将很多业务都要使用的功能进行抽取,在运行业务时; 再动态的植入这些抽取的代码。(将共性业务和核心业务分离).AOP实现了共性功能和核心功能的解耦;提高了共性功能的代码的复用率
    AOP和OOP互为补充,面向切面编程将程序运行过程分解成各个切面
    值得注意的是:AOP是一种设计思想,与具体的技术无关。

    AOP基础概念

            a、切面(Aspect):是一个类,是对横切关注点的抽象;切面用于组织多个Advice,Advice放在切面中定义。
    		
    		b、连接点(JoinPoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出。在Spring AOP中,连接点总是方法的调用。
    							  
    		c、切入点(Pointcut):匹配连接点的拦截规则。AOP的核心;可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。
    		
    		d、通知(Advice):在切面上拦截到某个特定的连接点之后执行的动作
    		
    		e、目标对象(Target Objcet):被一个或多个切面所通知的对象,即业务中需要进行增强的业务对象
    		
    		f、织入(Weaving):将切面作用到目标对象上,然后产生一个代理对象的过程
    		
    		g、引入(Introduction):用来在运行时给一个类声明额外的方法或属性,即不需要为类实现一个接口 就能使用接口中的方法。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Spring实现AOP

    导入所需的jar包:

    
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-aspectsartifactId>
          <version>${springVersion}version>
        dependency>
        <dependency>
          <groupId>org.springframeworkgroupId>
          <artifactId>spring-aopartifactId>
          <version>${springVersion}version>
        dependency>
        <dependency>
          <groupId>org.aspectjgroupId>
          <artifactId>aspectjweaverartifactId>
          <version>1.9.4version>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    基于CGLIB动态代理实现的AOP

    在这里;创建Dog、Fish实例;他们都有同一个放法eatFood();在这里以时间为切入点做示例

    package com.aop;
    
    /**
     * @author Una
     * @date 2022/8/11 17:34
     * @description:
     */
    
    
    public class Fish {
        public void eatFood(){
            System.out.println("开始吃鱼食!!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("吃完了鱼食!!!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    package com.aop;
    
    /**
     * @author Una
     * @date 2022/8/11 17:37
     * @description:
     */
    
    
    public class Dog {
        public void eatFood(){
            System.out.println("开始吃狗粮!!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束吃狗粮!!!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    切面文件

    package com.aop;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    /**
     * @author Una
     * @date 2022/8/11 17:40
     * @description:定义切面---即横向关注点(开始和结束的时间)
     */
    public class XmlSpilt {
        //打印开始的时间
        public  void startTime(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String startEatDate = sdf.format(new Date());
    
            System.out.println("开始时间是:"+startEatDate);
        }
        //打印结束的时间
        public void endTime(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String startEatDate = sdf.format(new Date());
            System.out.println("结束时间是:"+startEatDate);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    (1)采用XML格式的配置

    xml格式的配置则需要在resource包下创建spring配置文件

    
    <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="fish" class="com.aop.Fish"/>
        <bean id="dog" class="com.aop.Dog"/>
        <bean id="xmlSpilt" class="com.aop.XmlSpilt"/>
    
    
        <aop:config>
            <aop:aspect id="dateLog" ref="xmlSpilt">
                <aop:pointcut id="eatFood" expression="execution(* com.aop.*.*(..))"/>
                <aop:before method="startTime" pointcut-ref="eatFood"/>
                <aop:after method="endTime" pointcut-ref="eatFood"/>
            aop:aspect>
        aop:config>
    
        
        <aop:aspectj-autoproxy proxy-target-class="true"/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    测试文件

    
    /**
     * @author Una
     * @date 2022/8/11 17:47
     * @description:
     */
    public class XmlSpiltTest {
        @Test
        public void test2(){
            ApplicationContext ac=new ClassPathXmlApplicationContext("aop-conf.xml");
            Fish fish=(Fish) ac.getBean("fish");
            Dog dog=(Dog) ac.getBean("dog");
            fish.eatFood();
            System.out.println("----------------------");
            dog.eatFood();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (2)采用注解方式的实现

    如果采用注解的方式实现;在xm文件中;将不用配置;直接在相应的类文件中加入注解即可

          a、@Aspect注解:表示切面(类,由横切关注点抽象的类)
    	   
    	   b、@Pointcut注解:表示指定切入点
    	   
    	   c、@Before注解:表示前置通知
    	   
    	   d、@After注解:表示后置通知
    	   
    	   e、在配置中开启注解的扫描
    		   
    	   f、开启aop注解
    	   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    
    <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"
           xmlns:context="http://www.springframework.org/schema/context"
           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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
        <context:component-scan base-package="com.aop"/>
        
        <aop:aspectj-autoproxy proxy-target-class="true"/>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    package com.aop;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author Una
     * @date 2022/8/11 17:40
     * @description:定义切面---即横向关注点(开始和结束的时间)
     */
    
    @Component
    @Aspect
    public class XmlSpilt {
    
       //定义切入点方法
       @Pointcut("execution(* com.aop.*.*(..))")
        public void eatFood(){
    
        }
    
        //打印开始的时间
        @Before("eatFood()")
        public  void startTime(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String startEatDate = sdf.format(new Date());
            System.out.println("开始时间是:"+startEatDate);
        }
    
        //打印结束的时间
        @After("eatFood()")
        public void endTime(){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String startEatDate = sdf.format(new Date());
            System.out.println("结束时间是:"+startEatDate);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在Dog、Fish类中加入注解@Component

    package com.aop;
    
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/11 17:37
     * @description:
     */
    
    @Component
    public class Dog {
        public void eatFood(){
            System.out.println("开始吃狗粮!!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束吃狗粮!!!");
        }
    }
    ///
    package com.aop;
    
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/11 17:34
     * @description:
     */
    
    @Component
    public class Fish {
        public void eatFood(){
            System.out.println("开始吃鱼食!!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("吃完了鱼食!!!");
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    结果:
    在这里插入图片描述

  • 相关阅读:
    操作系统【OS】Ch2 大题 PV题型分类
    SpringSecurity(二十)---OAuth2:实现资源服务器(上)资源服务器搭建以及直接调用授权服务器模式
    FastDFS学习(三)
    不知道文字转语音软件哪个好?推荐几款实用软件
    科创人·连界董事长王玥:错误的成功约等于失败,创新服务要与企业共命运
    koa中使用koa-body获取post请求中的参数
    前端精度问题 (id 返回的和传给后端的不一致问题)
    python 线程池使用
    电子电气架构 --- 关于DoIP的一些闲思 下
    分布式存储系统之Ceph集群启用Dashboard及使用Prometheus监控Ceph
  • 原文地址:https://blog.csdn.net/m0_50744075/article/details/126283024