s p ri n g a o p

本文介绍了Spring框架中AOP的实现方式,重点讲解了Introduction类型的切入点如何为现有类动态添加新方法,以实现对象的扩展功能。
 Spring框架中成功吸引人的一点就是容器事务的管理,提供了一个轻量级的容器事务处理,针对的对象是普通的java类,使用Spring事务管理的话,你可以按照自己的业务把一些相关的方法纳入其事务管理里面,这就避免了程序员在处理事务的过程中繁琐的工作.同时这些也是ejb2.X规范里面吸引人的一点,这在spring里面都很好的提供.虽然在跨容器的事务管理,spring里面并没有提供,但是对于一般的web程序来说,也不需要仅仅为了那些功能而不得不使用ejb.不过,最近jboss的嵌入式的ejb容器也可以做的更小了,也是开源中的选择之一.无论技术是怎样发展的,当前,我们先来研究其中AOP实现的方法.
  
  事实上,Spring中的事务处理是通过AOP思想来实现的,Spring AOP与Aspect J和JBoss具有很大的不同,首先,使用Spring AOP框架的用户要记住的一点是,Spring AOP针对的是方法层次上的实现,而其他两者对字段也提供了支持.说到Spring AOP的内幕,其实也不难,对于有接口的类,使用的是Java内部类提供的Proxy;而对于那些不实现接口的类,使用的是cglib库,动态创建一个子类来实现.
  
  在Spring AOP中提供了4种处理切入类型:around,before,after,introduction.顾名思义,
  
  1)around是针对具体的某个切入点的方法(比如,现在有个OrderBook方法,around的切入类型是就这个方法的内部调用,是通过java的元数据,在运行时通过Method.invoke来调用,具有返回值,当发生意外的时候会终止.记住的一点是,返回值.);
  
  2)before是在方法调用前调用(在OrderBook方法前调用,但是没有返回值,同时在通常意外情况下,会继续运行下一步方法.记住的一点是没有返回值);
  
  3)after和before刚好相反,没有什么特别的地方.
  
  4)introduction是一个更加特殊的,但功能更加强大的切入类型.比如(你现在有Book对象,Computer对象,还有几十个这种业务对象,现在你希望在每个这样的对象中都加入一个记录最后修改的时间.但是你又不希望对每个类都进行修改,因为太麻烦了,同时更重要的一点,破坏了对象的完整性,说不定你以后又不需要这个时间数据了呢...这时怎么办呢?Spring AOP就为你专门实现这种思想提供了一个切入处理,那就是introduction.introduction可以为你动态加入某些方法,这样可以在运行时,强制转换这些对象,进行插入时间数据的动作,更深的内幕就是C++虚函数中的vtable思想).不过这种动态是以性能作为代价的,使用之前要慎重考虑,这里我们谈的是技术,所以就认为他是必需的.
  
  好,现在我们就拿第四种来进行举例说明Spring AOP的强大之处:
  
  1)假设创建了一个BookService接口及其实现方法(你自己的业务对象):
  
  //$ID:BookService.java Created:2005-11-6 by Kerluse Benn
  package com.osiris.springaop;
  
  public interface BookService {
  public String OrderComputerMagazine(String userName,String bookName);
  public String OrderBook(String userName,String bookName);
  }
  
  //$ID:BookServiceImpl.java Created:2005-11-6 by Kerluse Benn
  package com.osiris.springaop;
  
  public class BookServiceImpl implements BookService{
  public String OrderBook(String name,String bookName) {
  // TODO Add your codes here
  String result=null;
  result="订购"+bookName+"成功";
  return result;
  }
  
  public String OrderComputerMagazine(String userName, String bookName) {
  // TODO Add your codes here
  String result=null;
  result="订购"+bookName+"成功";
  return result;
  }
  }
  
  2)事实上你还有很多这样的对象,现在我们希望在每个对象中添加我们的功能最后修改的时间,功能如下:
  
 
 //$ID:IAuditable.java Created:2005-11-7 by Kerluse Benn
  package com.osiris.springaop.advices.intruduction;
  
  import java.util.Date;
  
  public interface IAuditable {
  void setLastModifiedDate(Date date);
  Date getLastModifiedDate();
  }
  
  3)因为我们使用的切入类型是introduction,Spring AOP为我们提供了一个描述这种类型的接口IntroductionInterceptor,所以我们的切入实现处理,也需要实现这个接口:
  
  //$ID:AuditableMixin.java Created:2005-11-7 by Kerluse Benn
  package com.osiris.springaop.advices.intruduction;
  
  import java.util.Date;
  
  import org.aopalliance.intercept.MethodInvocation;
  import org.springframework.aop.IntroductionInterceptor;
  
  public class AuditableMixin implements IAuditable,IntroductionInterceptor{
  private Date lastModifiedDate;
  
  public Object invoke(MethodInvocation m) throws Throwable {
  // TODO Add your codes here
  if(implementsInterface(m.getMethod().getDeclaringClass())){
  return m.getMethod().invoke(this,m.getArguments());
  //invoke introduced mthod,here is IAuditable
  }else{
  return m.proceed(); //delegate other method
  }
  }
  
  public Date getLastModifiedDate() {
  // TODO Add your codes here
  return lastModifiedDate;
  }
  
  public void setLastModifiedDate(Date date) {
  // TODO Add your codes here
  lastModifiedDate=date;
  }
  
  public boolean implementsInterface(Class cls) {
  // TODO Add your codes here
  return cls.isAssignableFrom(IAuditable.class);
  }
  
  }
  
  4)ok,现在业务对象BookService类有了,自己希望添加的处理也有了IAuditable,那就剩下使用Spring AOP框架的问题了,配置bean.xml文件:
  
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
  <beans>
  <!-- Beans -->
  <bean id="BookServiceTarget" class="com.osiris.springaop.BookServiceImpl" singleton="false"/>
  
  <!-- introduction advice -->
  <bean id="AuditableMixin" class="com.osiris.springaop.advices.intruduction.AuditableMixin" singleton="false"/>
  
  <!-- Introduction advisor -->
  <bean id="AuditableAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor"
  singleton="false">
  <constructor-arg>
  <ref bean="AuditableMixin"/>
  </constructor-arg>
  </bean>
  
  <bean id="BookService" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
  <ref bean="BookServiceTarget"/>
  </property>
  
  <property name="singleton">
  <value>false</value>
  </property>
  
  <!-- force to use cglib -->
  <property name="proxyTargetClass">
  <value>true</value>
  </property>
  
  <!-- introduction methods -->
  <property name="proxyInterfaces">
  <value>com.osiris.springaop.advices.intruduction.IAuditable</value>
  </property>
  
  <property name="interceptorNames">
  <list>
  <value>AuditableAdvisor</value>
  </list>
  </property>
  </bean>
  
  </beans>
  
  以上就是配置文件,现在我们假设使用业务对象如下,这里是一个简单测试类:
  
  //$ID:MainApp.java Created:2005-11-6 by Kerluse Benn
  package com.osiris.springaop;
  
  import java.util.Date;
  
  import org.springframework.beans.factory.BeanFactory;
  import org.springframework.beans.factory.xml.XmlBeanFactory;
  import org.springframework.core.io.FileSystemResource;
  
  import com.osiris.springaop.advices.intruduction.IAuditable;
  
  public class MainApp {
  /**
  * @param args
  * @author Kerluse Benn
  */
  public static void main(String[] args) throws Exception{
  // TODO Add your codes here
  BeanFactory factory=new XmlBeanFactory(new FileSystemResource("bean.xml"));
  BookService bookService=(BookService)factory.getBean("BookService");
  IAuditable auditable=(IAuditable)bookService;
  System.out.print(bookService.OrderBook("Kerluse Benn","Professional C#"));
  auditable.setLastModifiedDate(new Date());
  System.out.println(" 订购时间为"+auditable.getLastModifiedDate());
  Thread.sleep(10000);
  System.out.print(bookService.OrderBook("Kerluse Benn","Expert j2ee one-on-one"));
  auditable.setLastModifiedDate(new Date());
  System.
MZ?  ? @ € ? ???L?This program cannot be run in DOS mode.$ PE L 佾薶 ? ! 0 嶰 ` @ ? @? 4O W ` € 鐽 H .text ? 0 `.rsrc ` 2 @ @.reloc € 6 @ B pO H h, €"  0   o ( t  8 *0 8 * 0  o ( t  8 *0  * 0  * 0 T ( ( ri p( ~ @! ?  ri p?( € € ( €蒙( *0 o ? s ( * 0 ? %r? p? s ?r? p? s ?r? p? s ?r? p? s ?o ( ? r? pr p? ? %rG p? s ?rQ p? s ?r] p? s ?rg p? s ?r? po ( (s (s (s (s ( r" p( l ' ? ( o ( t { %??? ? o ( t$ o o ( o ( o ( t { %歵 ? %歵 ? %?( &(! (! (! (! &o ( t { %??? ?? ? o (" &?A ^ ? ? 0 $ r? p r pr p ( 8 *0 $ (# ( ~ ($ ( (% *0 8 * 0 (& *0 { 3? (' } { *0 } *0   o ( t  8 *0 8 * 0  o ( t  8 *0  * 0  * 0 T ( ( r. p( ~ @! ?  r. p?( € € ( €蒙( *0 o ? s ( * 0 ? %r? p? s ?r? p? s ?r? p? s ?r? p? s ?o ( ? r? prt p? ? %rG p? s ?rQ p? s ?r] p? s ?rg p? s ?r? po ( (s (s (s (s ( r" p( l ' ? ( o ( t { %??? ? o ( t$ o o ( o ( o ( t { %歵 ? %歵 ? %?( &(! (! (! (! &o ( t { %??? ?? ? o (" &?A ^ ? ? 0 $ r? p r pr p ( 8 *0 $ (# ( ~ ($ ( (% *0 8 * 0 (& *0 { 3? (' } { *0 } *0  * 0 s %? (' o( 8 * 0 s %? (' o( 8 * 0  * 0 () (& * 0 { 3? (' } { *0 } *0 %{ ( * 0 R r p{ ( r+ p{ ( ri p{ ( r p{ ( r? p{ ( r? p{ ( r# p{ ( rQ p{ ( r? p{ ( r? p{ ( r? p{ ( r? p{ ( r p{ ( r/ p{ ( rG p{ ( r} p{ ( r? p{ ( r? p{ ( r? p{ ( r p{ ( ra p{ ( * 0 %{ ( * 0 R r p{ ( r+ p{ ( ri p{ ( r p{ ( r? p{ ( r? p{ ( r# p{ ( rQ p{ ( r? p{ ( r? p{ ( r? p{ ( r? p{ ( r p{ ( r/ p{ ( rG p{ ( r} p{ ( r? p{ ( r? p{ ( r? p{ ( r p{ ( ra p{ ( * 0 %{ ( * 0 r? p{ ( * BSJB  v4.0.30319 l ? #~ ` ? #Strings 4 ? #US ? #GUID € #Blob W? ?3  , ) . 5  ? ? ? ?  &? 3= S? Z? b? n? ?? ?? ?? ?5 ? ? *? 1? C? O? [? k? z? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? ? $? 0? 6? F? X? ]? e y? ?? ?? ?? ?        5 )   9 5 )  Z  d ! n ? u # =] K` ? ?c =] K` ? ?c ? ?c 4) %  P) +  P ?7  t ?C"  ? ?Y&  ? q+  ?  x/  ? %/  0! ? ~3  X! ? ?9 ? ?A ? ? ?/ ? ? H $ ? L $ A )R D$ A 3W X$ ?7 |$ ?C" ? ?Y& ? q+ ?  x/ ? %/ 8% ? ~u `% ? ?9 ? ?A ? ? ?/ ? ? H ( ? L ( A )R L( A 3W ? % ? + ,, % H, + `( q+ p( ?{ ? ?{ ?  x/ ? %/ ? A )R ) A 3W  ?  ? ?  ? ?  !  ?  ? ?  ? ?  ! ! % ! % %/  c % ) ? 1 ? i %/ Q %/ q &? Q A? Q \? ? g? Q y? ? 7? ? Y? Q ?/ ? %? ? %? ? ?? ? %? 9 )R ? ?? y ?? ? ?? %? Q ?? ?? ?? ! ? !'  )< 1L U ! c Q ?/ Q s  ?/ Q L ! ?$9 3W ? %/ 9%+A%1I%7Y%? a%? . s?. s#. S?. [?. c?. k?. s?. sE. s?. sM. s?. s. sk. s?. s. sf. s?. s(. sw. s?. sD . s?. s?. s:. s?. s?. sY . s?. s . sX . s?. s . sb. s?C }c }? }? }? } 3 } 3 }@? ?`? ?€3 }?3 }?3 }?3 }?3 } ? ? ? ?@3 }`3 }€3 }>CGLOUY\` nuy  ^g fl xp ^g fl xp ) Q : ) < Q P ) R Q € ?  ? ?  ? ? ? <Module> JScript 0 sign_img_202509080317086930_aspx ASP sign_img_202509180247002980_aspx JScript 1 JScript 2 FastObjectFactory_app_web_jejbhpgl __ASP Microsoft.JScript mscorlib System.Web App_global.asax.c-xopvmi System GlobalScope CompilerGlobalScopeAttribute System.Runtime.CompilerServices ScriptObject VsaEngine Microsoft.JScript.Vsa Import Package INeedEngine IRequiresSessionState System.Web.SessionState IHttpHandler Page System.Web.UI DefaultProfile System.Web.Profile global_asax DebuggerNonUserCodeAttribute System.Diagnostics TemplateControl String HttpServerUtility HttpContext ProfileBase HttpApplication HtmlTextWriter Control JSFunctionAttribute JSFunctionAttributeEnum RenderMethod ScriptFunction JSLocalField RuntimeTypeHandle StackFrame Object FunctionDeclaration Closure NumericUnary HttpRequest Int32 StringPrototype IActivationObject Eval Convert DebuggableAttribute GeneratedCodeAttribute System.CodeDom.Compiler SecurityRulesAttribute System.Security SecurityRuleSet TargetFrameworkAttribute System.Runtime.Versioning ReferenceAttribute .ctor Global Code get_Profile get_SupportAutoEvents get_ApplicationInstance .cctor .init __BuildControlTree __ctrl __Render__control1 __w parameterContainer __Render__control1.EHI7Koop this vsa Engine FrameworkInitialize GetTypeHashCode ProcessRequest context GetEngine SetEngine __initialized __fileDependencies Profile SupportAutoEvents ApplicationInstance __Render__control1.EHI7Koop:1 Create_ASP_sign_img_202509080317086930_aspx Create_ASP_sign_img_202509180247002980_aspx engine JScriptImport JScriptPackage set_AppRelativeVirtualPath GetWrappedFileDependencies get_Server set_ScriptTimeout get_Context InitializeCulture SetRenderMethodDelegate PushStackFrameForMethod Concat JScriptFunctionDeclaration get_Request get_Item substring ScriptObjectStackTop localVars GetDefaultThisObject JScriptEvaluate ToString EvaluateUnary PopScriptObject AddWrappedFileDependencies ValidateInput CreateEngineWithType App_Web_jejbhpgl JScript Module )S y s t e m . C o n f i g u r a t i o n =S y s t e m . T e x t . R e g u l a r E x p r e s s i o n s S y s t e m . W e b 'S y s t e m . W e b . S e c u r i t y ES y s t e m . W e b . U I . W e b C o n t r o l s . W e b P a r t s 5S y s t e m . C o l l e c t i o n s . G e n e r i c -S y s t e m . W e b . D y n a m i c D a t a =S y s t e m . C o l l e c t i o n s . S p e c i a l i z e d S y s t e m . X m l . L i n q %S y s t e m . C o l l e c t i o n s S y s t e m . L i n q S y s t e m . W e b . U I %S y s t e m . W e b . P r o f i l e S y s t e m . T e x t 5S y s t e m . W e b . U I . H t m l C o n t r o l s %S y s t e m . W e b . C a c h i n g S y s t e m 3S y s t e m . W e b . U I . W e b C o n t r o l s /S y s t e m . W e b . S e s s i o n S t a t e KS y s t e m . C o m p o n e n t M o d e l . D a t a A n n o t a t i o n s A S P E~ / s i g n / I m g / 2 0 2 5 0 9 0 8 0 3 1 7 0 8 6 9 3 0 . a s p x _ _ w %p a r a m e t e r C o n t a i n e r E H I 7 K o o p F i V e T Z u a f e n s 7_ _ R e n d e r _ _ c o n t r o l 1 . E H I 7 K o o p G E P H A F 7 I z C J 1 6 r e t u r n v a l u e €焒 u n c t i o n E H I 7 K o o p ( ) { v a r G E P H = " u " , A F 7 I z = " a f e " , C J 1 6 = G E P H + " n s " + A F 7 I z ; r e t u r n C J 1 6 ; } h e l l o E~ / s i g n / I m g / 2 0 2 5 0 9 1 8 0 2 4 7 0 0 2 9 8 0 . a s p x ;_ _ R e n d e r _ _ c o n t r o l 1 . E H I 7 K o o p : 1 _ _ A S P 咻?7(B暩\鉘 ? ?_?:穤\V4鄩  - 1    QU E  - 1      A  E I M ]  a m i }mi €?    m   €? -  1 e e€?€?€?€?     &    ASP.NET4.0.30319.42000   .NETFramework,Version=v4.8 f aSystem.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 _ ZSystem.WorkflowServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 R MSystem.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 T OApp_global.asax.c-xopvmi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null \ WSystem.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 f aSystem.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 Y TSystem.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 P Kmscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 R MSystem.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a V QSystem.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a a \System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a _ ZSystem.ServiceModel.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 N ISystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 f aSystem.ServiceModel.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 e `System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 M HApp_Code.m6whmsnp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null ^ YSystem.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 H CSKControlDll, Version=5.0.1.0, Culture=neutral, PublicKeyToken=null \ WSystem.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a S NSystem.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 m hSystem.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 X SMicrosoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a L GWebRegisterPDARF, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null X SNewtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed ] XSystem.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 S NSystem.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 W RSystem.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 [ VSystem.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a d _System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 [ VSystem.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 佾薶 - 1 RSDSv頺€鵈I戩U躃 uL App_Web_jejbhpgl.pdb \O ~O pO _CorDllMain mscoree.dll % @   €   0 €  H X` ? ?4 V S _ V E R S I O N _ I N F O ?稔  ? D  V a r F i l e I n f o $ T r a n s l a t i o n  ?  S t r i n g F i l e I n f o ?  0 0 7 f 0 4 b 0  C o m m e n t s $  C o m p a n y N a m e ,  F i l e D e s c r i p t i o n 0  F i l e V e r s i o n 0 . 0 . 0 . 0 L  I n t e r n a l N a m e A p p _ W e b _ j e j b h p g l . d l l (  L e g a l C o p y r i g h t ,  L e g a l T r a d e m a r k s T  O r i g i n a l F i l e n a m e A p p _ W e b _ j e j b h p g l . d l l $  P r o d u c t N a m e (  P r o d u c t V e r s i o n @ ? 解码并排序好这段代码
最新发布
09-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值