zoukankan      html  css  js  c++  java
  • Spring AOP入门实例详解

    copy from: http://hi.baidu.com/guxing820/blog/item/a7e6e7ccbc717b1601e9288f.html

    Thanks for author!

    如果你正在研究Spring的AOP,那么我想这篇文章可以为你的入门提供一点点帮助!

    我想研究Spring AOP之前应该研究一下Java的动态代理和反射机制,理解这两个概念和用法也是理解

    Spring框架的基础,因为Spring框架里面大量的使用了动态代理和反射机制。

    当然,本文主要是讲解Spring的AOP,下面就开始走入正题!

    AOP(面向切面编程),可千万不要认为只有Spring里面才有AOP的概念,因为你可以在很多地方发现AOP的身影。如果你知道Servlet里面的过滤器是怎么一回事,那么你就可以理解面向切面编程了,理解起来不是很难,怕还是理解不了,就再举一个例子,比如你去火车站,门口会有一个物品检测,人们只要把东西放在机器里面过一下就可以检测了,检测机器可以理解为只有一台,物品是很多,只要物品经过了检查机器就会自动的去检查,这就是面向切面!可以理解检查机器是一个检查物品的公共的类,只要物品经过就会检查,物品里面不需要这个功能,这个是在经过的时候自动加上去的!

    也许例子举得不是很好,不知道现在有没有理解面向切面编程!

    为了很好的理解,我拿出一个简单的配置文件的例子来,这样也可以方便讲解和大家的理解!

    <?xml version="1.0" encoding="UTF-8"?>
    <beans
    xmlns="
    http://www.springframework.org/schema/beans"
    xmlns:xsi="
    http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <!-- 【 基本配置文件 】 -->

    <bean id="proxybean" class="org.springframework.aop.framework.ProxyFactoryBean">
       <property name="proxyInterfaces">
        <value>org.bling.spring.aop.BuyInterface</value>
       </property>
       <property name="target">
        <ref local="targetbean"/>
       </property>
       <property name="interceptorNames">
        <list>
         <value>beforeadvisor</value>
         <value>afteradvisor</value>
        </list>
       </property>  
    </bean>

    <!-- 【 类 】 -->
    <bean id="targetbean" class="org.bling.spring.aop.BuyInterfaceImpl"></bean>

       <!-- 【 Advisor 】 -->
       <bean id="beforeadvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice">
         <ref local="beforeadvice"/>
        </property>
        <property name="pattern">
         <value>org\.bling\.spring\.aop\.BuyInterface\.buy</value>
        </property>
       </bean>
      
       <bean id="afteradvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice">
         <ref local="afteradvice"/>
        </property>
        <property name="pattern">
         <value>org\.bling\.spring\.aop\.BuyInterface\.buy</value>
        </property>
       </bean>
      
       <!-- 【 Advice 】 -->
       <bean id="beforeadvice" class="org.bling.spring.aop.Before"></bean>
       <bean id="afteradvice" class="org.bling.spring.aop.After"></bean>

    </beans>

    上面是一个很简单的配置文件的例子,有四个注释,我们首先看最下面一个【 Advice 】(翻译为通知),这就是我们自己定义的通知,就比如是上面例子里面的检查机器,类名为了方便理解取名为Before(理解为入门的检查机器)和After(这里我加了一个出门的时候的一个检查机器,按需要可以自己要还是不要),类名自己定义,但是要注意,Before.java这个类既然是在入门之前检查,那么在Spring框架中使用就要实现它给我提供的一个org.springframework.aop.MethodBeforeAdvice接口,可以理解为这是Spring的规定,当然After.java这个类也是要实现一个org.springframework.aop.AfterReturningAdvice接口,这样Spring框架就认识了我们自定义的这两个类,在实现接口的同时肯定会有接口定义的方法要被实现,所以Before.java里面会有一个public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable方法,After.java里面有一个public void afterReturning(Object returnValue, Method method, Object[] args, Object target)    throws Throwable方法,这是必须实现的!这样,我们的通知就写完了!

    下面看【 Advisor 】,这个地方是将我们自定义的通知交给Spring的一个类,这个类是org.springframework.aop.support.RegexpMethodPointcutAdvisor,这个理解为是一个切点,其实也就是切点(Pointcut)的概念,将我们定义的通知注入进去,因为这个类有一个advice属性,说的深一点,可以理解为这个advice属性的定义是一个至少继承了我们两个通知方法接口的一个接口,这里自己好好的理解一下!这个类里面还有一个属性pattern,知道正则表达式的应该不难理解他的写法,这里是告诉Spring,我们这个通知要给哪个接口里面的哪个方法进行通知,注意点是要转义的(\.)!再次强调写到方法名!

    注册完我们的自定义通知就要看看【 类 】了,这个类就是我们要进行通知的一个类,只是简单的在Spring框架里面注册了一下,这个类没有什么特别的,就是实现了一个自定义的接口,因为Spring框架提倡面向接口编程。

    下面继续,就剩下最后一个【 基本配置文件 】,这个里面就是真正实现了面向切面的部分,这个bean的ID自己定义,但是class="org.springframework.aop.framework.ProxyFactoryBean",他的里面有几个属性,这里就是列出了本例中用到的几个,其他的以后深入了继续讲解,首先看proxyInterfaces属性,这个是声明我们被通知的类实现的接口,因为这里是一个接口,因为只有一个bean要被通知,多个接口请使用list,当然一个也可以使用list,继续看target属性,这个是将我们的目标bean注入进去,继续interceptorNames属性,这里就是我们的通知了,这里我加了两个通知,一个是之前,一个是之后!

    这样我们的第一个Spring的AOP实例就是完成了!

    下面给出各个类完整的代码,以供大家参考,配置文件代码上面就是,不再重复!

    **************************Before.java*********提前通知******************

    package org.bling.spring.aop;

    import java.lang.reflect.Method;

    import org.springframework.aop.MethodBeforeAdvice;

    public class Before implements MethodBeforeAdvice {

    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
       System.out.println("你好,欢迎光临!");
    }
    }

    ***************************After.java************之后通知*************

    package org.bling.spring.aop;

    import java.lang.reflect.Method;

    import org.springframework.aop.AfterReturningAdvice;

    public class After implements AfterReturningAdvice{

    public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
        throws Throwable {
       System.out.println("欢迎下次光临!");
    }
    }

    ***************************Buy.java*******接口**************************

    package org.bling.spring.aop;

    public interface BuyInterface {
    public void buy();
    }

    *******************BuyInterfaceImpl.java*******接口实现类****************

    package org.bling.spring.aop;

    public class BuyInterfaceImpl implements BuyInterface {

    public void buy() {
       System.out.println("去商店买了一个东西!");
    }
    }

    **********************MainTest.java*****运行测试类************

    package org.bling.spring.aop;

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

    public class MainTest {

    public static void main(String[] args) {
       ApplicationContext ac = new FileSystemXmlApplicationContext("src/applicationContext.xml");
       BuyInterface buy = (BuyInterface)ac.getBean("proxybean");
       buy.buy();
    }
    }

    本文为原创,如有不妥之处请大家给予指正!大家多交流

  • 相关阅读:
    maven+spark2.0.0最大连通分量
    Eclipse+maven+scala2.11.8+spark2.0.0的环境部署
    杀死mapreduce
    filter-自己的理解
    JS变量声明提升
    js==运算符强制转换规则
    html 文字间距
    如你所见,我开始用微博
    vue数据模拟
    vue项目目录介绍
  • 原文地址:https://www.cnblogs.com/pricks/p/1744468.html
Copyright © 2011-2022 走看看