AOP概念及代码演示

一,什么是AOP

(1)面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而是的业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

(3)使用登录的例子说明AOP

 二,AOP的概念

面向切片编程(AOP—Aspect Oriented Programming)可以说是对OOP(面向对象编程)的补充和完善,面向对象就是将事物的特性和行为抽象为一个对象,如people类有身高、体重、年龄等属性,也有吃饭、睡觉等行为。把这些特性和行为封装成一个类,然后可以统一调用。面向切片也可以举个例子,比如people类有自己的属性和行为,但是有小一部分人生病要去医院看病,看病这个业务逻辑就不属于哪一个类,因为people泛指所有人,所有人不会都看病。AOP就是把医院看病这一个业务逻辑功能抽取出来,然后动态把这个功能切入到需要的方法(或行为)中,需要的才切入,这样便于减少系统的重复代码,降低模块间的耦合度。常用到AOP的就是安全校验、日志操作、事务操作等,给你先定义好,然后在想用的地方用,这样不会影响已经在服务器运行的项目,然后又能注入新功能,灵活。我们开发dao->service->controller是纵向的,这个AOP就是横向切入,如横向切入一个日志Log,打印执行过程。
在这里插入图片描述

Spring AOP就是基于动态代理实现的, 分为两种代理,jdk动态代理(基于接口)和cglib代理(基于类的)。如果目标对象实现了接口,就用jdk动态代理,如果未实现接口就用cglib动态代理。虽然动态代理可以解决耦合问题,但比较抽象,复杂,属于底层实现代理模式,我们这里直接用AOP,AOP做了很多封装,只要调用API即可,简化开发,但是AOP底层原理还是需要了解。

注意:动态代理底层利用了反射机制,反射包下Proxy类,如果想了解底层原理的,推荐这个视频 动态代理详解。

Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
Target(目标对象):织入 Advice 的目标对象.。
Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程

三,AOP的作用

提供声明式事务;允许用户自定义切面

主要内容: 接口、实现类、核心类、配置类、测试类

 创建接口

public interface BookService {
    void findAll();

    void save(int a);

    int del();

    void update();
}

 实现类

public class BookServiceImpl implements BookService {
    public void findAll(){

        System.out.println("查找所有信息");
    }

    public void save(int a){

        System.out.println("保存信息+a");
    }

    public int del(){
        System.out.println("删除信息");
        return 0;
    }

    public void update(){

        System.out.println("修改信息");
    }

}

 核心类

public class Logger {
    public void check(){System.out.println("前置通知/增强;权限验证");}
    public void logPrint(){System.out.println("后置通知/增强;日志输出");}
    public void exception(){System.out.println("异常通知/增强;异常处理");}
    public void distroy(){System.out.println("最终通知/增强;资源释放");}
}

 配置类

<?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:context="http://www.springframework.org/schema/context"
       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/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--1.把所有类的对象交给IOC容器进行管理-->
    <bean id="logger" class="com.gao.logger.Logger" />
    <bean id="bookService" class="com.gao.service.impl.BookServiceImpl" />

    <!--2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法-->
    <aop:config>
        <!--指定增强类并起个名字-->
        <aop:aspect id="check" ref="logger">
            <!--前置通知/增强:在核心类方法执行之前 进行 增强-->
            <aop:before method="check" pointcut="execution(* *..BookServiceImpl.*(..))" />
            <aop:after-returning method="logPrint" pointcut="execution(* *..BookServiceImpl.*(..))" />
            <aop:after-throwing method="exception" pointcut="execution(* *..BookServiceImpl.*(..))" />
            <aop:after method="distroy" pointcut="execution(* *..BookServiceImpl.*(..))" />
        </aop:aspect>
    </aop:config>
</beans>

测试类

public class Test01 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        BookService bookService = context.getBean(BookService.class);
        bookService.findAll();
        bookService.save(5);
        bookService.del();
        bookService.update();
    }
}

运行结果:

猜你喜欢

转载自blog.csdn.net/weixin_69036336/article/details/129823947
今日推荐