Spring AOP 示例

解释就懒得写了,有代码运行一下就知道了,jar除了Spring所必备的以外还要加上bsh-1.2b7.jar

  1. packagecom.test;
  2. /**
  3. *在线图书销售系统业务逻辑接口
  4. */
  5. publicinterfaceBookBiz{
  6. publicfloat[]buy(StringuserName,StringbookName,doubleprice);
  7. publicvoidcomment(StringuserName,Stringcomments);
  8. }

  1. packagecom.test;
  2. publicclassBookBizImplimplementsBookBiz{
  3. /**
  4. *购买图书
  5. */
  6. publicfloat[]buy(StringuserName,StringbookName,doubleprice){
  7. System.out.println("业务方法buy开始执行");
  8. System.out.println("·"+userName+"购买图书:"+bookName);
  9. System.out.println("·"+userName+"增加积分:"+(int)(price/10));
  10. System.out.println("·"+"向物流系统下发货单");
  11. System.out.println("业务方法buy结束");
  12. returnnull;
  13. }
  14. /**
  15. *发表书评
  16. */
  17. publicvoidcomment(StringuserName,Stringcomments){
  18. System.out.println("业务方法comment开始执行");
  19. System.out.println("·"+userName+"发表书评"+comments);
  20. System.out.println("业务方法comment结束");
  21. }
  22. }
  1. packagecom.test;
  2. importjava.lang.reflect.Method;
  3. importjava.util.Arrays;
  4. importorg.aopalliance.intercept.MethodInterceptor;
  5. importorg.aopalliance.intercept.MethodInvocation;
  6. importorg.springframework.aop.AfterReturningAdvice;
  7. importorg.springframework.aop.MethodBeforeAdvice;
  8. importbsh.Interpreter;
  9. publicclassMyAdviceimplementsMethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor{
  10. /**
  11. *前通知
  12. */
  13. publicvoidbefore(Methodm,Object[]args,Objecttarget)
  14. throwsThrowable{
  15. System.out.println("前通知,调用的方法:"+m.getName()+",参数:"+Arrays.toString(args));
  16. }
  17. /**
  18. *后通知
  19. */
  20. publicvoidafterReturning(Objectonject,Methodmethod,Object[]args,
  21. Objectarg3)throwsThrowable{
  22. System.out.println("后通知,调用的方法:"+method.getName()+",参数:"+Arrays.toString(args));
  23. }
  24. /**
  25. *环绕通知,最维强大的通知,可以控制目标方法是否执行,也可以改变方法的返回值
  26. */
  27. publicObjectinvoke(MethodInvocationmethod)throwsThrowable{
  28. System.out.println("[环绕通知]");
  29. Object[]args=method.getArguments();
  30. /**
  31. *这里我们禁止李四发表任何的评论
  32. */
  33. if(method.getMethod().getName().equals("comment")&"李四".equals(args[0])){
  34. System.out.println("屏蔽李四所有的评论");
  35. StringreturnType=method.getMethod().getReturnType().getName();
  36. if("int".equals(returnType)||"long".equals(returnType)||"float".equals(returnType)||"double".equals(returnType)||"byte".equals(returnType)||"short".equals(returnType)){
  37. //利用BeanShell构造一个内置变量返回,这里想了好久,没有想到什么方法可以根据
  38. //指定数据类型返回指定的变量
  39. Interpreteri=newInterpreter();
  40. returni.eval("("+returnType+")0");
  41. }elseif("boolean".equals(returnType)){
  42. returnfalse;
  43. }
  44. returnnull;
  45. }else{
  46. returnmethod.proceed();
  47. }
  48. }
  49. }
  1. packagecom.test;
  2. importorg.springframework.context.ApplicationContext;
  3. importorg.springframework.context.support.ClassPathXmlApplicationContext;
  4. publicclassAOPTest{
  5. /**
  6. *@paramargs
  7. */
  8. publicstaticvoidmain(String[]args){
  9. ApplicationContextcontext=
  10. newClassPathXmlApplicationContext("springAop.xml");
  11. BookBizbookBiz=(BookBiz)context.getBean("bookBiz");
  12. bookBiz.buy("张三","Spring深入潜出",50);
  13. bookBiz.comment("李四","《恐怖世界》一点都不恐怖,很好看!");
  14. bookBiz.comment("张三","《Spring深入潜出》还是写得不错的!");
  15. }
  16. }
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
  3. <beans>
  4. <beanid="bookBizTarget"class="com.test.BookBizImpl"/>
  5. <beanid="myAdvice"class="com.test.MyAdvice"/>
  6. <beanid="bookBiz"class="org.springframework.aop.framework.ProxyFactoryBean">
  7. <propertyname="proxyInterfaces">
  8. <value>com.test.BookBiz</value>
  9. </property>
  10. <propertyname="interceptorNames">
  11. <list>
  12. <value>myAdvice</value>
  13. </list>
  14. </property>
  15. <propertyname="target"ref="bookBizTarget"/>
  16. </bean>
  17. </beans>

运行AOPTest 这个类,下面是输出结果:

[环绕通知]
前通知,调用的方法:buy,参数:[张三, Spring深入潜出, 50.0]
业务方法buy开始执行
·张三购买图书:Spring深入潜出
·张三增加积分:5
·向物流系统下发货单
业务方法buy结束
后通知,调用的方法:buy,参数:[张三, Spring深入潜出, 50.0]
[环绕通知]
屏蔽李四所有的评论
[环绕通知]
前通知,调用的方法:comment,参数:[张三, 《Spring深入潜出》还是写得不错的!]
业务方法comment开始执行
·张三发表书评《Spring深入潜出》还是写得不错的!
业务方法comment结束
后通知,调用的方法:comment,参数:[张三, 《Spring深入潜出》还是写得不错的!]

从输出结果可以看出,环绕通知是最先开始执行的,,如果环绕通知把目标方法屏蔽了不执行,那么后面的前后通知都不会执行

你可能感兴趣的:(spring,AOP,bean,xml,物流)