Spring AOP 是 Spring 框架的核心模块之一,它使用纯 Java 实现,因此不需要专门的编译过程和类加载器,可以在程序运行期通过代理方式向目标类织入增强代码。

Spring AOP 的代理机制
Spring 在运行期会为目标对象生成一个动态代理对象,并在代理对象中实现对目标对象的增强。

Spring AOP 的底层是通过以下 2 种动态代理机制,为目标对象(Target Bean)执行横向织入的。

Spring AOP 连接点
Spring AOP 并没有像其他 AOP 框架(例如 AspectJ)一样提供了完成的 AOP 功能,它是 Spring 提供的一种简化版的 AOP 组件。其中最明显的简化就是,Spring AOP 只支持一种连接点类型:方法调用。您可能会认为这是一个严重的限制,但实际上 Spring AOP 这样设计的原因是为了让  Spring 更易于访问。

方法调用连接点是迄今为止最有用的连接点,通过它可以实现日常编程中绝大多数与 AOP 相关的有用的功能。如果需要使用其他类型的连接点(例如成员变量连接点),我们可以将 Spring AOP 与其他的 AOP 实现一起使用,最常见的组合就是 Spring AOP + ApectJ。 

Spring AOP 通知类型
AOP 联盟为通知(Advice)定义了一个 org.aopalliance.aop.Interface.Advice 接口。

Spring AOP 通知类型
AOP 联盟为通知(Advice)定义了一个 org.aopalliance.aop.Interface.Advice 接口。

一般切面的 AOP 开发
当我们在使用 Spring AOP 开发时,若没有对切面进行具体定义,Spring AOP 会通过 Advisor 为我们定义一个一般切面(不带切点的切面),然后对目标对象(Target)中的所有方法连接点进行拦截,并织入增强代码。

AOP基于XML配置的入门案例:

首先是导入架包和创建所需要的包

spring 项目 apach jar包 spring apo_spring

接下来创建service类,这个类完成核心功能操作 

service类需要接口与实现类

先写接口:

public interface BookService {
    void findAll();
 
    void save(int a);
 
    int del();
 
    void update();
}

然后是它的实现类:

public class BookServiceImpl implements BookService {
    @Override
    public void findAll(){
 
        System.out.println("查询所有");
 
    }
 
    @Override
    public void save(int a) {
        System.out.println("保存信息"+a);
    }
 
    @Override
    public int del(){
        System.out.println("删除信息");
        return 5;
    }
 
    @Override
    public void update(){
 
        System.out.println("修改信息");
    }
}

service包中的代码我们现在假定其为不可更改的核心代码,接下来做的是在不更改核心代码的情况下对核心代码进行增强:

接下来是logger包下的类,在开发中主要用于AOP的增强

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("最终通知/增强:资源释放");}
}

接下来在src包中创建spring.xml,在里面配置加载

<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.zhang.logger.Logger"/>
    <bean id="bookService" class="com.zhang.service.impl.BookServiceImpl"/>
    <!-- 2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法 -->
    <aop:config>
        <!--2.AOP的配置:让增强类的那个方法 动态进行何种增强 核心类 的 那个方法-->
        <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>

所有的配置都完成的情况下,我们可以在servlet包中进行测试

public class Test01 {
 
    public static void main(String[] args) {
        //先加载spring配置文件,通过容器获取对象
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
        BookService bean = context.getBean(BookService.class);
 
        bean.findAll();
        bean.save(6);
        bean.del();
        bean.update();
    }
 
}