spring的aop原理演示(申明式以及配置式)

来源:互联网 发布:知乎怎么取消手机绑定 编辑:程序博客网 时间:2024/05/01 15:05

加载的jar有:

                           log4j-1.2.16.jar   

                           org.springfaramework.asm-3.0.5.release.jar

                           org.springfaramework.beans-3.0.5.release.jar

                           org.springfaramework.context-3.0.5.release.jar

                           org.springfaramework.core-3.0.5.release.jar

                           org.springfaramework.expression-3.0.5.release.jar

                           org.springfaramework.aop-3.0.5.release.jar

                           org.springfaramework.aspects-3.0.5.release.jar

                           aopalliance.jar

                           aspectjweaver-1.5.3.jar

                           asm-all.3.3.1.jar

                           cglib-2.2.2.jar

                           commons-logging-1.1.1.jar


文件结构图如下:

      


申明式:

MyService.java(目标类)

package org.baicai.spring.aop;

public class MyService {

    public MyService() {
    }
    public int div(String a,String b)
    {
        int inta=Integer.parseInt(a);
        int intb=Integer.parseInt(b);
        return inta/intb;
    }
}


MyAspect.java(切点)

package org.baicai.spring.anno.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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;

@Aspect
public class MyAspect {
   private static Logger logger= Logger.getLogger(MyAspect.class);
   
   public MyAspect() {
  }
   @Before("Pointcuts.pointcut()")
   public void beforeAdvice()
   {
       logger.info("执行前置通知");
   }
   @After("Pointcuts.pointcut()")
   public void afterAdvice()
   {
       logger.info("执行尾置通知");
   }
   @AfterReturning(pointcut="Pointcuts.pointcut()",returning="returnValue")
   public void afterReturningAdvice(Object returnValue)
   {
       logger.info("执行返回值尾通知:"+returnValue);
   }
   @AfterThrowing(pointcut="Pointcuts.pointcut()",throwing="ex")
   public void afterThrowException(Exception ex)
   {
       logger.info("捕获到异常信息:",ex);
   }
   @Around("Pointcuts.pointcut()")
   public Object aroundAdvice(ProceedingJoinPoint pjp)throws Throwable
   {
       Object returnValue=null;
       logger.info("进入环绕通知!");
       logger.info("进入类:"+pjp.getTarget().getClass().getName());
       logger.info("代理类:"+pjp.getThis().getClass().getName());
       logger.info("进入方法:"+pjp.getSignature().getName());
       Object[] args=pjp.getArgs();
       for (Object o : args) {
        logger.info(o+" ");
    }
       try{
       returnValue=pjp.proceed();
       logger.info("方法执行完成!");
       }catch (Exception e) {
        logger.info("捕获到异常信息:",e);
        throw e;
    } finally
    {
        logger.info("完成环绕通知!");
    }
       return returnValue;
   }
}


Pointcuts .java(切向范围)

package org.baicai.spring.anno.aop;

import org.aspectj.lang.annotation.Pointcut;


public class Pointcuts {
    /*第一个 * —— 通配 任意返回值类型
      第二个 * —— 通配 包org.baicai.spring下的任意class的任意方法
            .. —— 通配 方法可以有0个或多个参数
    */
  @Pointcut("execution(* org.baicai.spring..*(..))")
  public void pointcut()
    {
    }
}


Demo.java(演示)

package org.baicai.spring.anno.aop;

import org.apache.log4j.Logger;
import org.baicai.spring.aop.MyService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
    private static Logger logger=Logger.getLogger(Demo.class);
    
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("/context_anno_aop.xml");
        logger.debug("++++++++++++++++++++++++++++++++++");
        MyService service =context.getBean(MyService.class);
        logger.info(service.div("100","10"));
        logger.debug("++++++++++++++++++++++++++++++++++");
        try {
            logger.info(service.div("100", "abc"));
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        logger.debug("++++++++++++++++++++++++++++++++++");
    }
}

context_anno_aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
           
           <bean id="service" class="org.baicai.spring.aop.MyService" ></bean>
           <bean  id="myAspect" class="org.baicai.spring.anno.aop.MyAspect"></bean>
           
           <!-- 配置自动检测源注解切面 -->
           <aop:aspectj-autoproxy/>
           </beans>


配置式:

MyAspect.java

package org.baicai.spring.aop;

import org.apache.log4j.Logger;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspect {
      private static Logger logger = Logger.getLogger(MyAspect.class);
    
     public void beforeAdvice()
     {
        logger.info("执行前置通知") ;
     }
     public void afterAdvice()
     {
         logger.info("执行尾置通知");
     }
     public void afterReturingAdvice(Object returnValue)
     {
         logger.info("执行返回值尾置通知:"+returnValue);
     }
     public void afterThrowException(Exception ex)
     {
         logger.info("捕获到异常信息:",ex);
     }
     public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable
     {
         Object returnValue=null;
         logger.info("进入环绕通知!");
         logger.info("进入类:"+pjp.getTarget().getClass().getName());
         logger.info("代理类:"+pjp.getThis().getClass().getName());
         logger.info("进入方法:"+pjp.getSignature().getName());
         Object[] args = pjp.getArgs();
         System.out.print("方法参数:");
         for (Object o : args) {
            logger.info(o+" ");
        }
         try{
          //执行方法
           returnValue=pjp.proceed();
           logger.info("方法执行完成!");
         }catch(Exception ex)
         {
             logger.info("捕获到异常信息:",ex);
             throw ex;
         }finally
         {
             logger.info("完成环绕通知!");
         }
         return returnValue;
     }
}


Demo.java(演示)

package org.baicai.spring.aop;


import org.apache.log4j.Logger;
import org.baicai.spring.aop.MyService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class Demo {
        private static Logger logger=Logger.getLogger(Demo.class);
        
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("/context_config.xml");
            logger.debug("++++++++++++++++++++++++++++++++++");
            MyService service =context.getBean(MyService.class);
            logger.info(service.div("10","10"));
            logger.debug("++++++++++++++++++++++++++++++++++");
            try {
                logger.info(service.div("100", "abc"));
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
            logger.debug("++++++++++++++++++++++++++++++++++");
        }
}


context_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
           
           <bean id="service"  class="org.baicai.spring.aop.MyService"/>
           <!-- 切面配置 -->
              <!-- 处理切面的Bean-->
              <bean id="myAspect"  class="org.baicai.spring.aop.MyAspect"></bean>
           
           <aop:config>
               <!-- 切面表达式, ..表示任意级别和数量,*表示任意字符 -->
               <aop:pointcut expression="execution(* org.baicai.spring..*(..))" id="pointcut_one"/>
                <!--关联切面处理类和切面表达式的类,方法  -->
                <aop:aspect ref="myAspect">
                   <!-- 前置通知配置 -->
                   <aop:before method="beforeAdvice" pointcut-ref="pointcut_one"/>
                   <!-- 尾置通知配置 -->
                   <aop:after method="afterAdvice" pointcut-ref="pointcut_one"/>
                   <!-- 返回值尾置通知配置 -->
                   <aop:after-returning method="afterReturingAdvice" returning="returnValue"  pointcut-ref="pointcut_one"/>
                   <!-- 异常捕获通知配置 -->
                   <aop:after-throwing method="afterThrowException" throwing="ex" pointcut-ref="pointcut_one"/>
              
                  <!-- 更加完整和简洁的切面处理  环绕通知  -->
                   <aop:around method="aroundAdvice" pointcut-ref="pointcut_one"/>
                </aop:aspect>
           </aop:config>
</beans>

注:log4j.dtd,log4j.xml就不呈现出来了  见《struts1 一个很简单的登录演示》

运行结果如下(申明式和配置式的结果一致):

        










原创粉丝点击