SpringAOP切点配置(注解与xml配置)

  本文介绍介绍spring aop 的用法:注解和xml配置,最简洁的配置,最简单的介绍。

注解

  使用注解去配置aop非常的简单,只需要在spring的xml配置文件里激活component-scan功能指定需要扫描的包,将组件都初始化到spring的容器中。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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        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-4.1.xsd">

    <context:component-scan base-package="com.springinaction"/>
    <!-- 激活自动代理功能 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

  很简单,除了引入spring的一些命名空间外还有两行,一个是注册扫描功能并指定目标包、第二个是注册自动代理功能,这一点很重要,如果你不加入的话,spring就会抛出异常,我小白,没有能搞定其中的原理,在网上找了一个链接
动态代理

编写接口

  这里声明一个接口Performance,里面有perform()方法,如下

package com.springinaction.service;
public interface Performance {
    public void perform();

}

编写Actor实现接口

这里需要加上conponent的注解,是让spring初始化的时候被扫描到

package com.springinaction.service;

import org.springframework.stereotype.Component;

@Component
public class Actor implements Performance {

    @Override
    public void perform() {
        System.out.println("表演中...");
    }
}

编写一个切面

这个bean除了需要加上component的注解外,还需要加上aspectj的注解,让spring知道他不仅仅是一个组件,而且是一个切面。代码如下

package com.springinaction.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AudienceAnnotation {

    @Pointcut("execution(** com.springinaction.service.Performance.perform(..))")
    public void performance(){}

    @Before("performance()")
    public void takeSeats(){
        System.out.println("找座位");
    }

    @AfterReturning("performance()")
    public void applause(){
        System.out.println("再来一个");
    }

    @AfterThrowing("performance()")
    public void demandRefund(){
        System.out.println("垃圾,炒鸡垃圾");
    }

    @Around("performance()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{  
        System.out.println("进入环绕通知");  
        Object object = pjp.proceed();//执行该方法  
        System.out.println("退出环绕通知");  
        return object;  
    }
}

Pointcut注解的performance方法并没有实质性作用,这是为了扩展切点表达式语言,这样就可以在任何切点表达式中使用performance,当然不使用Pointcut你就要这样写

package com.springinaction.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AudienceAnnotation {


    @Before("execution(** com.springinaction.service.Performance.perform(..))")
    public void takeSeats(){
        System.out.println("找座位");
    }

    @AfterReturning("execution(** com.springinaction.service.Performance.perform(..))")
    public void applause(){
        System.out.println("再来一个");
    }

    @AfterThrowing("execution(** com.springinaction.service.Performance.perform(..))")
    public void demandRefund(){
        System.out.println("垃圾,炒鸡垃圾");
    }

    @Around("execution(** com.springinaction.service.Performance.perform(..))")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{  
        System.out.println("进入环绕通知");  
        Object object = pjp.proceed();//执行该方法  
        System.out.println("退出环绕通知");  
        return object;  
    }
}

不嫌麻烦,这也是可以的。下面是切点表达式的解释(照着springinaction上绘制的)
表达式介绍
只要实现Performanceperform的方法,就会依次执行@Before,@AfterReturning,@AfterThrowing。当然使用@Around方法可以代替以上三个注解。
下面看一下目录结构(先不用管红线划去的地方)
这里写图片描述

编写测试类

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.springinaction.service.Actor;

public class ShowTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-annotation.xml");
        Actor actor = (Actor)context.getBean("actor");
        actor.perform();
    }
}

运行结果为:

进入环绕通知
找座位
表演中...
退出环绕通知
再来一个

XML配置

使用xml,你就要注册每一个bean,也包括aspectJ,如下

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

    <bean id="oldClown" class="com.springinaction.service.OldClown" />

    <bean id="audienceXml" class="com.springinaction.aop.AudienceXml" />

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <aop:config>
        <aop:aspect id="aspect" ref="audienceXml">
            <aop:pointcut
                expression="execution(** com.springinaction.service.Performance.perform(..))"
                id="performance" />
            <aop:before method="takeSeats" pointcut-ref="performance" />
            <aop:after-returning method="applause"
                pointcut-ref="performance" />
            <aop:after-throwing method="demandRefund"
                pointcut-ref="performance" />
            <aop:around method="doBasicProfiling" pointcut-ref="performance" />
        </aop:aspect>
    </aop:config>

</beans>

上面没有注册spring扫描的功能,所有的bean都要自己去声明。aspect的配置要和下面的AudienceXml 一一对应。

编写OldClown实现接口

同样实现Performance 接口

package com.springinaction.service;
public class OldClown implements Performance {
    @Override
    public void perform() {
        System.out.println("老小丑演技更加佳");
    }
}

编写一个切面

这里的切面没有任何注解,所有的功能都在xml里配置了

package com.springinaction.aop;

import org.aspectj.lang.ProceedingJoinPoint;
public class AudienceXml {

    public void performance(){}

    public void takeSeats(){
        System.out.println("找座位");
    }

    public void applause(){
        System.out.println("再来一个");
    }

    public void demandRefund(){
        System.out.println("垃圾,炒鸡垃圾");
    }

    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{  
        System.out.println("进入环绕通知");  
        Object object = pjp.proceed();//执行该方法  
        System.out.println("退出环绕通知");  
        return object;  
    } 
}

编写测试类

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.springinaction.service.OldClown;

public class ShowTestXml {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-xml.xml");
        OldClown oldClown = (OldClown)context.getBean("oldClown");// TODO
        oldClown.perform();
    }
}

运行的结果为:

找座位
进入环绕通知
老小丑演技更加佳
退出环绕通知
再来一个

到此spring切点的注解与xml配置已经都已经完成,这些是springaop的最基本实现方式,具体的还要看所属的项目结构。

下一篇将会介绍springaop处理通知中的参数,还有本节所有的代码下载地址

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qqHJQS/article/details/53401743
文章标签: spring xml aop
个人分类: spring
所属专栏: spring-boot-quick
上一篇Maven系列(五)CentOS7搭建最新GitLab
下一篇SpringAOP 处理通知中的参数(注解与xml配置)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭