Spring中的AOP 面向切面编程

Spring中的AOP 面向切面编程

一,什么是AOP
AOP(Aspect Oriented Programming)面向切面编程,是Spring框架中的内容,它是针对于一个事件的某个步骤或阶段,主要应用于:日志,事务处理,异常处理等方面,它的原理是:通过过滤,对指定的一些操作直接添加设定好的方法,不需要频繁的调用,在不使用接口的情况下实现java的动态代理。
AOP技术利用一种称为“横切”的技术,剖解开封装对象的内部,将影响多个类的公共行为封装到一个可重用的模块中,并将其命名为Aspect切面。所谓的切面,简单来说就是与业务无关,却为业务模块所共同调用的逻辑,将其封装起来便于减少系统的重复代码,降低模块的耦合度,有利用未来的可操作性和可维护性。
利用AOP可以对业务逻辑各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发效率。
Spring AOP 模块提供拦截器来拦截一个应用程序,例如,当执行一个方法时,你可以在方法执行之前或之后添加额外的功能。
二 AOP术语
在这里插入图片描述
三 通知的类型
Spring 方面可以使用下面提到的五种通知:
在这里插入图片描述
四 Spring 中基于AOP的XML架构
以银行系统的存款和转账流程来说,其中都存在相同的验证流程,AOP思想则是将这些相同的流程抽离出来,以存钱/转账方法为切入点,分别在此切入点之前或之后建立配置。
代码展示:
为了在本节的描述中使用 aop 命名空间标签,你需要导入 spring-aop j架构,如下所述:

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

首先创建存款和转账的接口

package cn.tb.dao;

public interface BankDao {
    
    
    //存钱
    public void saveMoney();

    //转账
    public void remirt();
}

然后设置相关流程
验证事务

package cn.tb.impl;

public class AdminCheck {
    
    
    public void check(){
    
    
        System.out.println("权限验证开始");
    }
}

处理和提交事务

package cn.tb.impl;

import org.aspectj.lang.ProceedingJoinPoint;

public class TransactionManager {
    
    

    public void beginTransaction(){
    
    
        System.out.println("开始事务处理");
    }

    public void commitTrnasaction(){
    
    
        System.out.println("提交事务处理");
    }

    public void doInceptor(ProceedingJoinPoint point) throws Throwable{
    
    
        beginTransaction();
        point.proceed();
        commitTrnasaction();
    }
}

执行相关操作

package cn.tb.impl;

import cn.tb.dao.BankDao;

public class BankDaoImpl implements BankDao{
    
    
    @Override
    public void saveMoney() {
    
    
        System.out.println("正在存钱");
    }

    @Override
    public void remirt() {
    
    
        System.out.println("正在转账");
    }
}

日志写入

package cn.tb.impl;

public class LogManager {
    
    
    //日志
    public void writeLog(){
    
    
        System.out.println("日志正在写入");
    }
}

最后配置完整的Spring 中基于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
                           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-->
    <bean class="cn.tb.impl.AdminCheck" id="adminCheck"></bean>
    <bean class="cn.tb.impl.BankDaoImpl" id="bankDao"></bean>
    <bean class="cn.tb.impl.LogManager" id="logManager"></bean>
    <bean class="cn.tb.impl.TransactionManager" id="transactionManager"></bean>

    <!--开始spring aop 面向切面配置-->
    <aop:config>
        
        <!--切入点 什么时机,什么时候切入-->
        <aop:pointcut id="serviceInceptor" expression="execution(* cn.tb.impl.*.*(..))"></aop:pointcut>

        <!--前置通知 在一个方法执行之前,执行通知。-->
        <aop:aspect ref="adminCheck">
            <aop:before method="check" pointcut-ref="serviceInceptor"></aop:before>
        </aop:aspect>

        <!--环绕通知 在建议方法调用之前和之后,执行通知。-->
        <aop:aspect ref="transactionManager">
            <aop:around method="doInceptor" pointcut-ref="serviceInceptor"></aop:around>
        </aop:aspect>

        <!--后置通知 在一个方法执行之后,不考虑其结果,执行通知。-->
        <aop:aspect ref="logManager">
            <aop:after method="writeLog" pointcut-ref="serviceInceptor"></aop:after>
        </aop:aspect>
    </aop:config>
</beans>

测试

package cn.tb.test;

import cn.tb.dao.BankDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        test1();
        System.out.println("-------------");
        test2();
    }
    //存钱
    private static void test1() {
    
    
        ApplicationContext alc = new ClassPathXmlApplicationContext("Spring.xml");
        BankDao dao = alc.getBean("bankDao", BankDao.class);
        dao.saveMoney();
    }
    //转账
    private static void test2() {
    
    
        ApplicationContext alc = new ClassPathXmlApplicationContext("Spring.xml");
        BankDao dao = alc.getBean("bankDao", BankDao.class);
        dao.remirt();
    }
}

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

猜你喜欢

转载自blog.csdn.net/tan1024/article/details/114938762
今日推荐