1.简介
Spring 中的AOP为Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。以下是Spring AOP的小例子
2.例子简介
2.1切面aspect:Logging.java
- package edu.njupt.zhb;
- public class Logging {
-
- public void beforeAdvice(){
- System.out.println("Logging:before... ");
- }
-
- public void afterAdvice(){
- System.out.println("Logging:after... ");
- }
-
- 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
- package edu.njupt.zhb;
- 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:config>
- <aop:aspect id="logStudent" ref="myLogging">
-
- <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;
-
-
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
- public class TestMain {
-
-
- public static void main(String[] args) {
-
- 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) {
-
- 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)
- package edu.njupt.zhb;
-
- import org.aspectj.lang.JoinPoint;
-
- 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... ");
- }
-
- 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...
未经允许,不得用于商业目的