其他分享
首页 > 其他分享> > Spring AOP 详解以及 Spring 使用 XML 配置 AOP

Spring AOP 详解以及 Spring 使用 XML 配置 AOP

作者:互联网

一、概述

1、AOP

2、作用:

3、优势:

4、AOP 的实现方式

二、AOP(面向切面编程)

1、AOP 相关术语

2、spring 中的 AOP 要明确的事

a、开发阶段(程序员做的)

b、运行阶段(Spring 框架完成的)

三、XML 配置 AOP 步骤

第一步:配置要搜索的包

<context:component-scan base-package="cn.lemon"></context:component-scan>

第二步:使用 aop:config 声明 aop 配置

<!--aop 配置
     # proxy-target-class="true":使用CGLib代理,默认是 接口代理(JDK代理)
-->
<aop:config proxy-target-class="true">
        <!--配置的代码都写在此处-->
</aop:config>

第三步:使用 aop:aspect 配置切面

<aop:aspect ref="loggerAdvice">
     <!--配置通知的类型要写在此处-->
</aop:aspect>

第四步:使用 aop:pointcut 配置切入点表达式

<!--切入点表达式:定义那些方法织入增强-->
<aop:pointcut id="serviceMethod" expression="execution(* cn.lemon.service.impl.*.*(..))"></aop:pointcut><!--切入点-->

切入点表达式说明
表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
全匹配方式:

public void cn.lemon.service.impl.AccountServiceImpl.addAccount(cn.lemon.domain.Account)

访问修饰符可以省略

void cn.lemon.service.impl.AccountServiceImpl.addAccount(cn.lemon.domain.Account)

返回值可以使用*号,表示任意返回值

* cn.lemon.service.impl.AccountServiceImpl.addAccount(cn.lemon.domain.Account)

包名可以使用*号,表示任意包,但是有几级包,需要写几个*

 * *.*.*.*.AccountServiceImpl.addAccount(cn.lemon.domain.Account)

使用..来表示当前包,及其子包

 * cn..AccountServiceImpl.addAccount(cn.lemon.domain.Account)

类名可以使用*号,表示任意类

 * cn..*.addAccount(cn.lemon.domain.Account)

方法名可以使用*号,表示任意方法:

 * cn..*.*( cn.lemon.domain.Account)

参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数:

 * com..*.*(*)

参数列表可以使用..表示有无参数均可,有参数可以是任意类型:

 * com..*.*(..)

全通配方式:

 * *..*.*(..)

注意:
通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。

execution(* com.lxs.service.impl.*.*(..))

第五步:使用 aop:xxx 配置对应的通知类型

<aop:before method="before" pointcut-ref="serviceMethod"></aop:before><!--织入前置增强-->
<aop:after-returning method="afterReturning" pointcut-ref="serviceMethod" returning="result"></aop:after-returning><!--后置增强-->
<aop:around method="around" pointcut-ref="serviceMethod"></aop:around><!--环绕增强-->
<aop:after-throwing method="exception" pointcut-ref="serviceMethod" <aop:after method="after" pointcut-ref="serviceMethod"></aop:after><!--最终增强-->

在这里插入图片描述

四、Spring 使用 XML 配置 AOP

1、新建持久层(dao),接口以及实现类

package cn.lemon.dao;

public interface IAccountDao {
    void in(Double money);

    void out(Double money);
}
package cn.lemon.dao.impl;

import cn.lemon.dao.IAccountDao;
import org.springframework.stereotype.Repository;

@Repository
public class AccountDaoImpl implements IAccountDao {
    @Override
    public void in(Double money) {
        System.out.println("成功转入" + money + "元钱");
    }

    @Override
    public void out(Double money) {
        System.out.println("成功转出" + money + "元钱");
    }
}

2、新建业务层(service),接口以及实现类

package cn.lemon.service;

public interface IAccountService {
    void transfer(Double money);
}
package cn.lemon.service.impl;

import cn.lemon.dao.IAccountDao;
import cn.lemon.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AccountServcieImpl implements IAccountService {
    @Autowired
    private IAccountDao iAccountDao;

    @Override
    public void transfer(Double money) {
        iAccountDao.in(money);
        iAccountDao.out(money);
    }
}

3、增强类

package cn.lemon.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;

@Component
public class LoggerAdvice {
    /**
     *
     * @param joinPoint 得到业务方法的信息
     *                  getSignature() 表示签名
     */
    public void before(JoinPoint joinPoint){
        System.out.println("开启事务:前置增强,方法名为:" + joinPoint.getSignature().getName());
    }
    public void afterReturning(JoinPoint joinPoint,Object result){
        System.out.println("提交事务:后置增强,方法名为:" + joinPoint.getSignature().getName() + "返回值为:" + result);
    }

    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前置增强.......");
        //执行业务方法
        Object result = proceedingJoinPoint.proceed();
        System.out.println("环绕后置增强。。。。。。");
        return result;
    }

    public void exception(JoinPoint joinPoint,Exception e){
        System.out.println("异常增强,异常信息为:" + e.getMessage());
    }

    public void after(JoinPoint joinPoint){
        System.out.println("最终增强,方法名为;" + joinPoint.getSignature().getName());
    }
}

4、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: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">
    <context:component-scan base-package="cn.lemon"></context:component-scan>

    <!--aop 配置
     # proxy-target-class="true":使用CGLib代理,默认是 接口代理(JDK代理)
    -->
    <aop:config proxy-target-class="true">
        <!--切入点表达式:定义那些方法织入增强-->
        <aop:pointcut id="serviceMethod" expression="execution(* cn.lemon.service.impl.*.*(..))"></aop:pointcut><!--切入点-->
        <aop:aspect ref="loggerAdvice">
            <aop:before method="before" pointcut-ref="serviceMethod"></aop:before><!--织入前置增强-->
            <aop:after-returning method="afterReturning" pointcut-ref="serviceMethod" returning="result"></aop:after-returning><!--后置增强-->
            <aop:around method="around" pointcut-ref="serviceMethod"></aop:around><!--环绕增强-->
            <aop:after-throwing method="exception" pointcut-ref="serviceMethod" throwing="e"></aop:after-throwing><!--异常增强-->
            <aop:after method="after" pointcut-ref="serviceMethod"></aop:after><!--最终增强-->
        </aop:aspect>
    </aop:config>
</beans>

5、测试类

package cn.lemon.service.impl;

import cn.lemon.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/applicationContext.xml")
public class AccountServcieImplTest {
    @Autowired
    private IAccountService iAccountService;

    @Test
    public void transfer() {
        iAccountService.transfer(1000d);
    }
}

五、Spring 使用注解&XML 配置 AOP

标签:XML,lemon,cn,Spring,void,AOP,import,public
来源: https://blog.csdn.net/weixin_43860260/article/details/100524269