文档章节

Spring学习笔记(15)-----------Spring转折点(2)

Simon丶Ma
 Simon丶Ma
发布于 2016/04/14 14:56
字数 1368
阅读 3
收藏 0

  利用方式一的配置起来,可见代码还是非常的厚重的,定义一个切面就要定义一个切面类,然而切面类中,就一个通知方法,着实没有必要。所以Spring提供了,依赖aspectj的schema配置和基于aspectj 注解方式。这两种方式非常简介方便使用,也是项目中普遍的使用方式。梳理之:

4、方式二:schema配置

a、业务类:

/**
 * 业务类
 * 
 */
public class AspectBusiness {

    /**
     * 切入点
     */
    public String delete(String obj) {
        System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========\n");
        return obj + ":瞄~";
    }

    public String add(String obj) {
        System.out.println("================这个方法不能被切。。。============== \n");
        return obj + ":瞄~ 嘿嘿!";
    }

    public String modify(String obj) {
        System.out.println("=================这个也设置加入切吧====================\n");
        return obj + ":瞄改瞄啊!";
    }

}



b、切面类:切面类中,包含了所有的通知


/**
 * 定义一个切面
 * 
 * @author yanbin
 * 
 */
public class AspectAdvice {

    /**
     * 前置通知
     * 
     * @param jp
     */
    public void doBefore(JoinPoint jp) {
        System.out.println("===========进入before advice============ \n");

        System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
        System.out.print(jp.getSignature().getName() + "方法进行对 '");
        System.out.print(jp.getArgs()[0] + "'进行删除!\n\n");

        System.out.println("要进入切入点方法了 \n");
    }

    /**
     * 后置通知
     * 
     * @param jp
     *            连接点
     * @param result
     *            返回值
     */
    public void doAfter(JoinPoint jp, String result) {
        System.out.println("==========进入after advice=========== \n");
        System.out.println("切入点方法执行完了 \n");

        System.out.print(jp.getArgs()[0] + "在");
        System.out.print(jp.getTarget().getClass() + "对象上被");
        System.out.print(jp.getSignature().getName() + "方法删除了");
        System.out.print("只留下:" + result + "\n\n");
    }

    /**
     * 环绕通知
     * 
     * @param pjp
     *            连接点
     */
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("===========进入around环绕方法!=========== \n");

        // 调用目标方法之前执行的动作
        System.out.println("调用方法之前: 执行!\n");

        // 调用方法的参数
        Object[] args = pjp.getArgs();
        // 调用的方法名
        String method = pjp.getSignature().getName();
        // 获取目标对象
        Object target = pjp.getTarget();
        // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
        Object result = pjp.proceed();

        System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + result + "\n");
        System.out.println("调用方法结束:之后执行!\n");
    }

    /**
     * 异常通知
     * 
     * @param jp
     * @param e
     */
    public void doThrow(JoinPoint jp, Throwable e) {
        System.out.println("删除出错啦");
    }

}
 

c、配置文件:

<?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:p="http://www.springframework.org/schema/p"
    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-3.0.xsd     
          http://www.springframework.org/schema/context     
          http://www.springframework.org/schema/context/spring-context-3.0.xsd 
          http://www.springframework.org/schema/aop     
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
    default-autowire="byName">

    <!-- ==============================利用spring 利用aspectj来配置AOP================================ -->

    <!-- 声明一个业务类 -->
    <bean id="aspectBusiness" class="aop.schema.AspectBusiness" />

    <!-- 声明通知类 -->
    <bean id="aspectAdvice" class="aop.schema.advice.AspectAdvice" />

    <aop:config>
        <aop:aspect id="businessAspect" ref="aspectAdvice">
            <!-- 配置指定切入的对象 -->
            <aop:pointcut id="point_cut" expression="execution(* aop.schema.*.*(..))" />
            <!-- 只匹配add方法作为切入点
            <aop:pointcut id="except_add" expression="execution(* aop.schema.*.add(..))" />
             -->

            <!-- 前置通知 -->
            <aop:before method="doBefore" pointcut-ref="point_cut" />
            <!-- 后置通知 returning指定返回参数 -->
            <aop:after-returning method="doAfter"
                pointcut-ref="point_cut" returning="result" />
            <aop:around method="doAround" pointcut-ref="point_cut"/>
            <aop:after-throwing method="doThrow" pointcut-ref="point_cut" throwing="e"/>
        </aop:aspect>
    </aop:config>
</beans>

d、测试类:

public class Debug {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("aop/schema_aop.xml");
        AspectBusiness business = (AspectBusiness) context.getBean("aspectBusiness");
        business.delete("猫");
    }
}

5、方式三:aspectj注解

注解在项目中已经到处都是了,撇开一些优劣不提,开发的便利性和可读性是非常的方便的。用来配置Spring AOP也非常简单便利

a、业务类:

/**
 * 业务类
 * 
 */
@Component
public class Business {

    /**
     * 切入点
     */
    public String delete(String obj) {
        System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========\n");
        return obj + ":瞄~";
    }

    public String add(String obj) {
        System.out.println("================这个方法不能被切。。。============== \n");
        return obj + ":瞄~ 嘿嘿!";
    }

    public String modify(String obj) {
        System.out.println("=================这个也设置加入切吧====================\n");
        return obj + ":瞄改瞄啊!";
    }

}

b、切面类:

/**
 * 定义切面
 * 
 * @Aspect : 标记为切面类
 * @Pointcut : 指定匹配切点
 * @Before : 指定前置通知,value中指定切入点匹配
 * @AfterReturning :后置通知,具有可以指定返回值
 * @AfterThrowing :异常通知
 * 
 * @author yanbin
 * 
 */
@Component
@Aspect
public class AspectAdvice {

    /**
     * 指定切入点匹配表达式,注意它是以方法的形式进行声明的。
     */
    @Pointcut("execution(* aop.annotation.*.*(..))")
    public void anyMethod() {
    }

    /**
     * 前置通知
     * 
     * @param jp
     */
    @Before(value = "execution(* aop.annotation.*.*(..))")
    public void doBefore(JoinPoint jp) {
        System.out.println("===========进入before advice============ \n");

        System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
        System.out.print(jp.getSignature().getName() + "方法进行对 '");
        System.out.print(jp.getArgs()[0] + "'进行删除!\n\n");

        System.out.println("要进入切入点方法了 \n");
    }

    /**
     * 后置通知
     * 
     * @param jp
     *            连接点
     * @param result
     *            返回值
     */
    @AfterReturning(value = "anyMethod()", returning = "result")
    public void doAfter(JoinPoint jp, String result) {
        System.out.println("==========进入after advice=========== \n");
        System.out.println("切入点方法执行完了 \n");

        System.out.print(jp.getArgs()[0] + "在");
        System.out.print(jp.getTarget().getClass() + "对象上被");
        System.out.print(jp.getSignature().getName() + "方法删除了");
        System.out.print("只留下:" + result + "\n\n");
    }

    /**
     * 环绕通知
     * 
     * @param pjp
     *            连接点
     */
    @Around(value = "execution(* aop.annotation.*.*(..))")
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("===========进入around环绕方法!=========== \n");

        // 调用目标方法之前执行的动作
        System.out.println("调用方法之前: 执行!\n");

        // 调用方法的参数
        Object[] args = pjp.getArgs();
        // 调用的方法名
        String method = pjp.getSignature().getName();
        // 获取目标对象
        Object target = pjp.getTarget();
        // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
        Object result = pjp.proceed();

        System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + result + "\n");
        System.out.println("调用方法结束:之后执行!\n");
    }

    /**
     * 异常通知
     * 
     * @param jp
     * @param e
     */
    @AfterThrowing(value = "execution(* aop.annotation.*.*(..))", throwing = "e")
    public void doThrow(JoinPoint jp, Throwable e) {
        System.out.println("删除出错啦");
    }

}

c、配置:

View Code
<?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:p="http://www.springframework.org/schema/p"
    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-3.0.xsd     
          http://www.springframework.org/schema/context     
          http://www.springframework.org/schema/context/spring-context-3.0.xsd 
          http://www.springframework.org/schema/aop     
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
    default-autowire="byName">

    <context:component-scan base-package="aop.annotation" />
    <!-- 打开aop 注解 -->
    <aop:aspectj-autoproxy />

</beans>

d、测试类:

本文借鉴http://www.cnblogs.com/yanbincn/archive/2012/08/13/2636961.html

作者相当给力,写的很不错呀@这回aop可以学的明白些了!

© 著作权归作者所有

共有 人打赏支持
Simon丶Ma
粉丝 4
博文 134
码字总数 299850
作品 0
深圳
程序员
私信 提问
springmvc+mybatis学习笔记(汇总)

springmvc+mybatis学习笔记(汇总) 标签 : springmvc mybaits [TOC] 笔记分为两大部分:mybatis和springmvc mybatis springmvc 笔记内容主要是mybatis和springmvc的一些基本概念和使用方法,...

brianway
2016/03/30
1K
2
springmvc学习笔记(6)-springmvc整合mybatis(IDEA中通过maven构建

springmvc学习笔记(6)-springmvc整合mybatis(IDEA中通过maven构建) 标签: springmvc mybatis [TOC] 本文主要展示如何在intellij IDEA中通过maven构建springmvc+mybatis框架的开发环境。 需求...

brianway
2016/03/10
432
0
【Spring Boot】1.基础知识

前言 该相关文档其实是学习一段名为“尚硅谷Spring Boot的学习视频”的过程中所做的笔记,教导老师讲解的非常细腻,推荐大家去支持一下。 简介 spring boot是用来简化Spring应用开发。 约定大...

落花时节又逢卿
2018/12/27
0
0
maven下整合spring和quartz

最近在研究Spring中的定时任务功能,最好的办法当然是使用Quartz来实现。对于一个新手来说,花了我不少时间,这里我写个笔记,给大家参考。 我使用的是Maven来管理项目,需要的Jar包我给大家...

明舞
2014/07/28
0
4
工作4年多才学会怎么去读源码,可悲么?

最近慢慢的尝试去看spring的源码,学习spring,以前都是只会用就行了,但是越是到后面,发现只是懂怎么用还不够,在面试的时候也会经常被问到一些开源框架的源码问题,即使在网上各种百度,当...

麦克斯
01/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java并发编程基础(三)

线程间通信 线程间通信称为进程内通信,多个线程实现互斥访问共享资源时会互相发送信号货这等待信号,比如线程等待数据到来的通知,线程收到变量改变的信号。 线程阻塞(同步)和非阻塞(异步)...

chendom
7分钟前
1
0
阿里重磅开源首款自研科学计算引擎Mars,揭秘超大规模科学计算

日前,阿里巴巴正式对外发布了分布式科学计算引擎 Mars 的开源代码地址,开发者们可以在pypi上自主下载安装,或在Github上获取源代码并参与开发。 此前,早在2018年9月的杭州云栖大会上,阿里...

阿里云官方博客
17分钟前
1
0
我是怎样和Linux系统结缘并通过红帽RHCE认证的

我高考完当时就是选择的计算机科学与技术专业,上大学以后联想到的和计算机相关的就只有写代码,开发,网站,网页设计,就没有其他的了,当时学习写代码也都是在Windows上,什么C#、C++之类的...

问题终结者
26分钟前
1
0
SSH之端口转发

第一部分 概述 当你在咖啡馆享受免费 WiFi 的时候,有没有想到可能有人正在窃取你的密码及隐私信息?当实验室的防火墙阻止了你的网络应用端口,是不是有苦难言?来看看 SSH 的端口转发功能带...

无语年华
31分钟前
1
0
我是怎样和Linux系统结缘并通过红帽RHCE认证的

我高考完当时就是选择的计算机科学与技术专业,上大学以后联想到的和计算机相关的就只有写代码,开发,网站,网页设计,就没有其他的了,当时学习写代码也都是在Windows上,什么C#、C++之类的...

linuxprobe16
49分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部