设为首页 加入收藏

TOP

我们为什么要使用 AOP(三)
2017-10-16 10:29:33 】 浏览:10525
Tags:我们 为什么 使用 AOP
hod method = methodSignature.getMethod(); System.out.println(method.getName() + "()方法开始时间:" + System.currentTimeMillis()); try { pjp.proceed(); System.out.println(method.getName() + "()方法结束时间:" + System.currentTimeMillis()); } catch (Throwable e) { } } } }

到第8行的代码与第12行的代码分别打印方法开始执行时间与方法结束执行时间。我这里写得稍微复杂点,使用了<aop:around>的写法,其实也可以拆分为<aop:before>与<aop:after>两种,这个看个人喜好。

这里多说一句,切面方法printTime本身可以不用定义任何的参数,但是有些场景下需要获取调用方法的类、方法签名等信息,此时可以在printTime方法中定义JointPoint,Spring会自动将参数注入,可以通过JoinPoint获取调用方法的类、方法签名等信息。由于这里我用的<aop:around>,要保证方法的调用,这样才能在方法调用前后输出时间,因此不能直接使用JoinPoint,因为JoinPoint没法保证方法调用。此时可以使用ProceedingJoinPoint,ProceedingPointPoint的proceed()方法可以保证方法调用,但是要注意一点,ProceedingJoinPoint只能和<aop:around>搭配,换句话说,如果aop.xml中配置的是<aop:before>,然后printTime的方法参数又是ProceedingJoinPoint的话,Spring容器启动将报错。

接着看一下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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/aop


http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="daoImpl" class="org.xrq.spring.action.aop.DaoImpl" />
    <bean id="timeHandler" class="org.xrq.spring.action.aop.TimeHandler" />

    <aop:config>
        <aop:pointcut id="addAllMethod" expression="execution(* org.xrq.spring.action.aop.Dao.*(..))" />
        <aop:aspect id="time" ref="timeHandler">
            <aop:before method="printTime" pointcut-ref="addAllMethod" />
            <aop:after method="printTime" pointcut-ref="addAllMethod" />
        </aop:aspect>
    </aop:config>
    
</beans>

我不大会写expression,也懒得去百度了,因此这里就拦截Dao下的所有方法了。测试代码很简单:

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public class AopTest {

    @Test
    @SuppressWarnings("resource")
    public void testAop() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring/aop.xml");
        
        Dao dao = (Dao)ac.getBean("daoImpl");
        dao.insert();
        System.out.println("----------分割线----------");
        dao.delete();
        System.out.println("----------分割线----------");
        dao.update();
    }
    
}

结果就不演示了。到此我总结一下使用AOP的几个优点:

  1. 切面的内容可以复用,比如TimeHandler的printTime方法,任何地方需要打印方法执行前的时间与方法执行后的时间,都可以使用TimeHandler的printTime方法
  2. 避免使用Proxy、CGLIB生成代理,这方面的工作全部框架去实现,开发者可以专注于切面内容本身
  3. 代码与代码之间没有耦合,如果拦截的方法有变化修改配置文件即可

下面用一张图来表示一下AOP的作用:

我们传统的编程方式是垂直化的编程,即A–>B–>C–>D这么下去,一个逻辑完毕之后执行另外一段逻辑。但是AOP提供了另外一种思路,它的作用是在业务逻辑不知情(即业务逻辑不需要做任何的改动)的情况下对业务代码的功能进行增强,这种编程思想的使用场景有很多,例如事务提交、方法执行之前的权限检测、日志打印、方法调用事件等等。

AOP使用场景举例

上面的例子纯粹为了演示使用,为了让大家更加理解AOP

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇这些年,安放在我工位上的那些书 下一篇Redis 和 Memcached 的区别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目