ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring入门系列:篇6——再探SpringAOC(SpringAOC的使用)

2020-07-01 15:54:44  阅读:479  来源: 互联网

标签:入门 Spring void SpringAOC System println import public out


前言

前面一篇文章中我们简单介绍了SpringAOP的作用以及原理,接下来我们来讲讲SpringAOP怎么配置使用。

一、SpringAOP的基本使用

还是使用上篇中的例子,假设我们需要给GoodsDao类进行增强:

public class GoodsDao {
    public void save() {
        System.out.println("goodsDao-----save");
    }
}

1.编写切面类

切面类中主要包含了多个通知(增强功能所封装成的方法)

public class MyAspectXML {
    public void check() {
        System.out.println("增加权限校验");
    }
}

2.配置applicationContext.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 id="goodsDao" class="demo1.GoodsDao"></bean>
    <bean id="myAspect" class="demo2.MyAspectXML"></bean>

    <!--配置Aop-->
    <aop:config>
        <!--配置切点:需要增强的方法-->
        <aop:pointcut id="savePoint" expression="execution(* demo1.GoodsDao.save(..))"/>
        <!--配置切面:如何增强、增强的功能-->
        <aop:aspect ref="myAspect">
            <aop:before method="check" pointcut-ref="savePoint"/>
        </aop:aspect>

    </aop:config>

</beans>

第一步:配置applicationContext肯定是将需要增强的类、切面类交由Spring管理

    <bean id="goodsDao" class="demo1.GoodsDao"></bean>
    <bean id="myAspect" class="demo2.MyAspectXML"></bean>

第二步:在aop配置配置切点,我们当然要指定需要被增强的方法(切点)。expression表达式指定需要配置的方法,*表示任意返回值..表示任意参数。

<!--配置切点:需要增强的方法-->
<aop:pointcut id="savePoint" expression="execution(* demo1.GoodsDao.save(..))"/>

第三步:配置切面,配置完切点我们还需要配置切面来通知Spring需要增强的内容是什么,以及如何进行增强

<!--配置切面:如何增强、增强的功能-->
<aop:aspect ref="myAspect">
<aop:before method="check" pointcut-ref="savePoint"/>
</aop:aspect>

3.测试

import demo1.GoodsDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AspectTest {

    @Resource(name = "goodsDao")
    GoodsDao goodsDao;

    @Test
    public void test() {
        goodsDao.save();
    }
}

运行结果:

增加权限校验
goodsDao-----save

二、SpringAOP通知类型

在动态代理中我们提到过我们可以在方法前面进行增强,也可以在方法后进行增强,springAOP也是如此,给我们提供了下面几种方式:

  • 前置通知(before):在方法执行前通知
  • 后置通知(after-returning):在方法执行后通知
  • 环绕通知(around):在方法执行前后通知
  • 异常抛出通知(after-throwing):在方法发生异常时通知
  • 最终通知(after):无论是否发生异常都通知

我们先将GoodsDao修改一下:

public class GoodsDao {
    public void save() {
        System.out.println("goodsDao-----save");
    }

    public String delete() {
        System.out.println("delete");
        return "delete---return";
    }

    public void update() {
        System.out.println("update");
    }

    public void find() {
        System.out.println("find");
        int a = 1/0;
    }

}

接着修改一下切面类:

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectXML {
    public void check() {
        System.out.println("增加权限校验");
    }

    public void writeLog(Object res) {
        System.out.println(res);
        System.out.println("记入日志");
    }

    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around------前置通知");
        joinPoint.proceed();
        System.out.println("around------后置通知");
    }

    public void exceptionNotice(Throwable e) {
        System.out.println("发生了异常:"+ e.getMessage());
    }

    public void finalNotice() {
        System.out.println("final--------------");
    }

}

配置applicationContex.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 id="goodsDao" class="demo1.GoodsDao"></bean>
    <bean id="myAspect" class="demo2.MyAspectXML"></bean>

    <!--配置Aop-->
    <aop:config>
        <!--配置切点:需要增强的方法-->
        <aop:pointcut id="savePoint" expression="execution(* demo1.GoodsDao.save(..))"/>
        <aop:pointcut id="deletePoint" expression="execution(* demo1.GoodsDao.delete(..))"/>
        <aop:pointcut id="updatePoint" expression="execution(* demo1.GoodsDao.update(..))"/>
        <aop:pointcut id="findPoint" expression="execution(* demo1.GoodsDao.find(..))"/>
        <!--配置切面:如何增强、增强的功能-->
        <aop:aspect ref="myAspect">
            <!--前置通知-->
            <aop:before method="check" pointcut-ref="savePoint"/>
            <!--后置通知-->
            <aop:after-returning method="writeLog" returning="res" pointcut-ref="deletePoint"/>
            <!--环绕通知-->
            <aop:around method="around" pointcut-ref="updatePoint"/>
            <!--异常抛出通知-->
            <aop:after-throwing method="exceptionNotice" throwing="e" pointcut-ref="findPoint"/>
            <!--最终通知-->
            <aop:after method="finalNotice" pointcut-ref="findPoint"/>

        </aop:aspect>

    </aop:config>

</beans>

测试类:

import demo1.GoodsDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AspectTest {

    @Resource(name = "goodsDao")
    GoodsDao goodsDao;

    @Test
    public void test() {
        goodsDao.save();
        System.out.println("--------------------------------------------");
        goodsDao.delete();
        System.out.println("--------------------------------------------");
        goodsDao.update();
        System.out.println("--------------------------------------------");
        goodsDao.find();
    }
}

运行结果:

增加权限校验
goodsDao-----save
--------------------------------------------
delete
delete---return
记入日志
--------------------------------------------
around------前置通知
update
around------后置通知
--------------------------------------------
find
final--------------
发生了异常:/ by zero

三、SpringAOP注解编程

我们可以将上面的程序改为注解的形式:

修改applicationContex.xml,需要在配置中开启aop注解:

<?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 id="goodsDao" class="demo1.GoodsDao"></bean>
    <bean id="myAspect" class="demo2.MyAspectXML"></bean>

    <!--AOP开启注解-->
    <aop:aspectj-autoproxy/>
</beans>

修改切面类,用法与配置文件形式基本相同:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class MyAspectXML {

    @Before(value = "execution(* demo1.GoodsDao.save(..))")
    public void check() {
        System.out.println("增加权限校验");
    }

    @AfterReturning(value = "execution(* demo1.GoodsDao.delete(..))" , returning = "res")
    public void writeLog(Object res) {
        System.out.println(res);
        System.out.println("记入日志");
    }

    @Around(value = "execution(* demo1.GoodsDao.update(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around------前置通知");
        Object proceed = joinPoint.proceed();
        System.out.println("around------后置通知");
        return proceed;
    }

    @AfterThrowing(value = "execution(* demo1.GoodsDao.find(..))" , throwing = "e")
    public void exceptionNotice(Throwable e) {
        System.out.println("发生了异常:"+ e.getMessage());
    }

    @After(value = "execution(* demo1.GoodsDao.find(..))")
    public void finalNotice() {
        System.out.println("final--------------");
    }

}
注解切入点的配置

有时候我们想在一个切点中即添加前置通知,又添加异常通知和最终通知该如何操作呢?

我们可以在切面当中定义好切入点:

import org.aspectj.lang.annotation.*;

@Aspect
public class MyAspectXML2 {
    @Before(value = "MyAspectXML2.pointcut1()")
    public void check() {
        System.out.println("增加权限校验");
    }

    @AfterThrowing(value = "MyAspectXML2.pointcut1()" , throwing = "e")
    public void exceptionNotice(Throwable e) {
        System.out.println("发生了异常:"+ e.getMessage());
    }

    @After(value = "MyAspectXML2.pointcut1()")
    public void finalNotice() {
        System.out.println("final--------------");
    }

    @Pointcut(value = "execution(* demo1.GoodsDao.save(..))")
    public void pointcut1(){}//定义好切点
}

标签:入门,Spring,void,SpringAOC,System,println,import,public,out
来源: https://www.cnblogs.com/ThinMoon/p/13219644.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有