1.简介
Spring 中的AOP为Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。以下是Spring AOP的小例子
2.例子简介
2.1切面aspect:Logging.java
/* * $filename: Logging.java,v $ * $Date: 2013-12-10 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2013-12-10 Nanjing,njupt,China */ public class Logging { public void beforeAdvice(){ System.out.println("Logging:before... "); } public void afterAdvice(){ System.out.println("Logging:after... "); } /** * * @param retVal 函数的返回值 */ public void afterReturningAdvice(Object retVal){ if(retVal==null){ return; } System.out.println("Logging:return :"+retVal.toString()); } public void afterThrowingAdvice(IllegalArgumentException ex){ System.out.println("Logging:exception:"+ex.toString()); } }
2.2Bean: Student.java
/* * $filename: Student.java,v $ * $Date: 2013-12-10 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2013-12-10 Nanjing,njupt,China */ public class Student { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void printThrowException(){ System.out.println("Exception in Student.class..."); throw new IllegalArgumentException("Exception from Student..."); } public void print(String say){ System.out.println("Say:"+say+",Name = "+name); } }
2.3xml文件配置
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- 切面类 --> <bean id="myLogging" class="edu.njupt.zhb.Logging"></bean> <!-- AOP配置 --> <aop:config> <aop:aspect id="logStudent" ref="myLogging"> <!-- pointcut配置 --> <aop:pointcut id="allMethod" expression="execution(* edu.njupt.zhb.*.*(..))"/> <aop:before pointcut-ref="allMethod" method="beforeAdvice"/> <aop:after pointcut-ref="allMethod" method="afterAdvice"/> <aop:after-returning pointcut-ref="allMethod" returning="retVal" method="afterReturningAdvice"/> <aop:after-throwing pointcut-ref="allMethod" throwing="ex" method="afterThrowingAdvice"/> </aop:aspect> </aop:config> <bean id="student" class="edu.njupt.zhb.Student"> <property name="id" value="1012010638"></property> <property name="name" value="Haibo Zheng"></property> </bean> </beans>
2.4测试
package edu.njupt.zhb; /* * $filename: TestMain.java,v $ * $Date: 2013-12-10 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2013-12-10 Nanjing,njupt,China */ public class TestMain { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student)context.getBean("student"); System.out.println("-------------"); student.getId(); System.out.println("-------------"); student.getName(); System.out.println("-------------"); student.print("Hi,I am a student"); System.out.println("-------------"); try{ student.printThrowException(); }catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } } }
2.5运行结果:
2013-12-10 18:32:54 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@145e044: display name [org.springframework.context.support.ClassPathXmlApplicationContext@145e044]; startup date [Tue Dec 10 18:32:54 CST 2013]; root of context hierarchy 2013-12-10 18:32:54 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] 2013-12-10 18:32:54 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory 信息: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@145e044]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1f4cbee 2013-12-10 18:32:54 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1f4cbee: defining beans [myLogging,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,allMethod,student]; root of factory hierarchy ------------- Logging:before... Logging:after... Logging:return :1012010638 ------------- Logging:before... Logging:after... Logging:return :Haibo Zheng ------------- Logging:before... Say:Hi,I am a student,Name = Haibo Zheng Logging:after... ------------- Logging:before... Exception in Student.class... Logging:after... Logging:exception:java.lang.IllegalArgumentException: Exception from Student... Exception from Student...
上述的方法只是在执行函数前,加一些自己的逻辑。如果完成更加复杂的功能,我们可能需要知道函数的名称以及函数的参数及其值等等信息。此时,我们只需要修改Logging类即可,可以修改为如下:(主要是使用了Spring aop中的JointPoint)
/* * $filename: Logging.java,v $ * $Date: 2013-12-10 $ * Copyright (C) ZhengHaibo, Inc. All rights reserved. * This software is Made by Zhenghaibo. */ package edu.njupt.zhb; import org.aspectj.lang.JoinPoint; /* *@author: ZhengHaibo *web: http://blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2013-12-10 Nanjing,njupt,China */ public class Logging { public void beforeAdvice(JoinPoint jointPoint){ Object methodArgs[] = jointPoint.getArgs();//获取切入点函数的参数 for(Object arg:methodArgs){ System.out.println("Logging:args type="+arg.getClass().getName()); System.out.println("Logging:args value="+arg); } System.out.println("Logging:ClassName="+jointPoint.getTarget().getClass().getName()); System.out.println("Logging:MethodName="+jointPoint.getSignature().getName()); System.out.println("Logging:before... "); } public void afterAdvice(){ System.out.println("Logging:after... "); } /** * * @param retVal 函数的返回值 */ public void afterReturningAdvice(Object retVal){ if(retVal==null){ return; } System.out.println("Logging:return :"+retVal.toString()); } public void afterThrowingAdvice(IllegalArgumentException ex){ System.out.println("Logging:exception:"+ex.toString()); } }
此时的运行结果为:
2013-12-10 19:44:07 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@145e044: display name [org.springframework.context.support.ClassPathXmlApplicationContext@145e044]; startup date [Tue Dec 10 19:44:07 CST 2013]; root of context hierarchy 2013-12-10 19:44:07 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] 2013-12-10 19:44:07 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory 信息: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@145e044]: org.springframework.beans.factory.support.DefaultListableBeanFactory@787d6a 2013-12-10 19:44:07 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@787d6a: defining beans [myLogging,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,allMethod,student]; root of factory hierarchy ------------- Logging:ClassName=edu.njupt.zhb.Student Logging:MethodName=getId Logging:before... Logging:after... Logging:return :1012010638 ------------- Logging:ClassName=edu.njupt.zhb.Student Logging:MethodName=getName Logging:before... Logging:after... Logging:return :Haibo Zheng ------------- Logging:args type=java.lang.String Logging:args value=Hi,I am a student Logging:args type=java.lang.Integer Logging:args value=20 Logging:ClassName=edu.njupt.zhb.Student Logging:MethodName=print Logging:before... Say:Hi,I am a student,Name = Haibo Zheng,age = 20 Logging:after... ------------- Logging:ClassName=edu.njupt.zhb.Student Logging:MethodName=printThrowException Logging:before... Exception in Student.class... Logging:after... Logging:exception:java.lang.IllegalArgumentException: Exception from Student... Exception from Student...
未经允许,不得用于商业目的