spring AOP

来源:互联网 发布:印尼排华 知乎 编辑:程序博客网 时间:2024/04/29 19:36

连接点(Joint Point):运行程序执行过程中需要插入aspect模块的某一点,如方法,属性,构造函数,类静态初始块,强调的是一个具体的点

切入点(Pointcuts): 指一个或多相连接点,可以理解成一个点的集合。如"execution(*Component.*(..))"表示Component类中所有心方法执行过程中,包括了3个连接点(method1,method2,method3)的集合.另外类中的所有方法调用,所有方法抛出错误,所有getter或setter方法执行,都可以作为切入点。切入点还支持组合(||,&&,!).如:

pointcut setter():target(UserInfo) && (call(void set*(String)) || call(void set*(int)))

表示所有UserInfo类中的所有带一个String或int型参数的setter方法

pointcut transaction():target(service..) && call(* save*(..))

表示service包中所有以save开头的方法

自动代理:

1: BeanNameAutoProxyCreator

<bean id=”beanNameAutoProxyCreator” class=”org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator”> 

<property name=’beanNames”> 

    <list>   <value>*Service</value>  </list> 

</property>

 <property name=”interceptorNames”>  

<value>throwsAdvice</value> 

</property>

</bean>

所有以Service结尾的bean都会由Spring自动创建代理,从而实现Advice的织入

 2: DefaultAdvisorAutoProxyCreator

<bean id=”autoProxyCreator” class=”org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator”>

 <bean id=”logAdvisor” class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>      <property name=”advice”>       

   <ref bean=”log”/>    

</property>   

   <property name=”patterns”>

//patterns 属性指出指定要代理的方法,使用的是正则表达式      

    <value>.*doAuditing.*</value> 

      </property>

 </bean>

 所有以doAuditing.*的方法都会由由Spring自动创建代理,从而实现Advice的织入

 3: 非自动代理

(1)java动态代理

<bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactoryBean ”>  

// 第一个属性,是指明要代理的类的接口,因为这个例子中使用的是Java动态代理机制来实现AOP的,因此必须指明接口    

<property name=”proxyInterfaces”>       

  <value>com.gc.impl.TimeBookInterface</value>   

  </property>

 // 这个属性是指明代理目标(target)类  

  <property name=”target”>      

   <ref bean=”timeBook”/>   

  </property>   

 // 这个属性是用来指明插入哪个Advice,此处使用list,应该表示这个类不只是可以调用这一个通知   

  <property name=”interceptorNames”>     

     <list> <value>log</value> </list>   

  </property>

 </bean>

 (2)cglib代理类<bean id=”logProxy” class=”org.springframework.aop.framework.ProxyFactoryBean”>

// 增加如下属性,就表示使用的是CGLIB代理(对目标类直接代理)

  <property name=”proxyTargetClass”>

  <value>true</value>

 </property>  

/* 然后去掉下面的属性,也就是说此种方法不需要面向接口,或不需要指出接口

 /*<property name=”proxyInterfaces”>     

    <value>com.gc.impl.TimeBookInterface</value>

    </property> */    

 <property name=”target”>  

       <ref bean=”timeBook”/>

 </property>

 <property name=”interceptorNames”>

  <list>   

 <value>log</value>  

 </list>  

</property>

</bean>

通知类型:

1: MethodInterceptor 环绕通知 实现接口 public Objectinvoke(MethodInvocation methodInvocation) throws Throwable

2: MethodBeforeAdvice 方法前通知 实现接口 public void before(Method method, Object[] args, Object target) throws Throwable

3: AfterReturningAdvice 方法后通知 实现接口 public void afterReturning(Method method, Object[] args, Object target) throws Throwable

 4: afterThrowing 异常通知 实现接口 public void afterThrowing(Method method, Object[] args, Object target,Throwable subclass) throws Throwable

测试程序: ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");  TimeBookInterface timeBookProxy = (TimeBookInterface)actx.getBean("timeBook");  timeBookProxy.doAuditing(" 张三 ");      

参考资料:http://blog.csdn.net/vvggsky/archive/2007/02/09/1505954.aspx