手记

Spring基础使用(三)-------XML定义AOP的使用

1、AOP实现方式

预编译方式:AspectJ

动态代理方式(JDK动态代理,CGLIB动态代理):Spring AOP,JbossAOP

2、基本概念

切面(Aspect):对程序进行切割的类,描述切割的点和切割前后需要执行的动作。

连接点(Joinpoint):符合切入点条件的某个具体的点。

通知(Advice):对应切面中要执行的某个动作。

切入点(Pointcut):切面要切割程序的位置。

引入(Introduction):

目标对象(Target Object):被切割的对象

3、通知的类型

前置通知(Before advice):在连接点之前执行的通知。前置通知不能阻止连接点的执行,除非抛出异常。

后置通知(After advice):在连接点之后执行的通知。

返回后通知(After returning advice):在连接点正常完成退出后执行的通知。

异常后通知(After throwing advice):在连接点抛出异常退出后执行的通知。

环绕通知(Around advice):包围连接点的通知,可以在连接点前后执行某些操作。

4、常用切入点表达式

执行所有的public方法:

      `execution(public * *(..))`

执行所有以set开始的方法:

      `execution(* set*(..))`

执行HelloSpringService类中的所有方法:

      `execution(* com.learn.service.HelloSpringService.*(..))`

执行service包中的所有方法:

      `execution(* com.learn.service..(..))`

执行service包及子包下的所有方法:

      `execution(* com.learn.service...(..))`
5、程序示例

xml文件中添加对aop的支持

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

声明切面,切面中添加切入点和通知

    <bean id="myAspect" class="learn.service.MyAspect"></bean>
    <bean id="helloService" class="learn.service.HelloServiceImpl"></bean>  

  <aop:config>
        <aop:pointcut id="pointcut1" expression="execution(* learn.service.HelloServiceImpl.serviceSave(..))"/>
        <aop:pointcut id="pointcut2" expression="execution(* learn.service.HelloServiceImpl.serviceSay(String))
            and args(word)"/>

        <aop:aspect id="aspectTest" ref="myAspect">
            <!--前置通知-->
            <aop:before method="beforeAdvice" pointcut-ref="pointcut1"></aop:before>
            <!--返回后通知-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut1"/>
            <!--后置通知-->
            <aop:after method="afterAdvice" pointcut-ref="pointcut1"/>
            <!--异常后通知-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut1"/>
            <!--无参环绕通知-->
            <aop:around method="aroundAdvice" pointcut-ref="pointcut1"/>
            <!--带参环绕通知-->
            <aop:around method="aroundAdvice2" pointcut-ref="pointcut2"/>
        </aop:aspect>
    </aop:config>

切面类

public class MyAspect {
    public void beforeAdvice()
    {
        System.out.println("beforeAdvice | before advice");
    }

    public void afterReturning()
    {
        System.out.println("afterReturning | after returning advice");
    }
    public void afterAdvice()
    {
        System.out.println("afterAdvice | after advice");
    }
    public void afterThrowing()
    {
        System.out.println("afterThrowing | after throwing advice");
    }
    public void aroundAdvice(ProceedingJoinPoint pdj) throws Throwable
    {
        System.out.println("aroundAdvice | 1 around  advice");
        pdj.proceed();
        System.out.println("aroundAdvice | 2 around  advice");
    }
    public void aroundAdvice2(ProceedingJoinPoint pdj, String word) throws Throwable
    {
        System.out.println("aroundAdvice2 | 1 around  advice");
        pdj.proceed();
        System.out.println("aroundAdvice2 | 2 around  advice");
    }
}
6、Introductions

Introductions为匹配到的Bean类型增加一个父类接口,并在指定的类中增加该接口的实现细节。

xml配置

    <aop:config>
        <aop:pointcut id="pointcut1" expression="execution(* learn.service.HelloServiceImpl.serviceSave(..))"/>

        <aop:aspect id="aspectTest" ref="myAspect">
            <aop:declare-parents types-matching="learn.service.HelloServiceImpl"
                                 implement-interface="learn.interfaces.Singer"
                                 default-impl="learn.service.SingerImpl"/>
        </aop:aspect>
    </aop:config>

接口

package learn.interfaces;

public interface Singer {
    void sing();
}

实现类

package learn.service;

import learn.interfaces.Singer;

public class SingerImpl implements Singer {
    public void sing() {
        System.out.println("sing a song!!");
    }
}

验证程序

        Singer helloService = (Singer) context.getBean("helloService");
        helloService.sing();

输出

sing a song!!
4人推荐
随时随地看视频
慕课网APP