spring中最强大的Advisor-DefaultPointcutAdvisor

  NameMatchMethodPointcutAdvisor和RegexMethodPointcutAdvisor提供了对一定命名规则和正则表达式切入点的封装,defaultPointcutAdvisor则提供了一切切入点的支持,Spring提供了4种用来定义切入的类,分别为:org.springframework.aop.support.NameMatchMethodPointcut、org.springframework.aop.support.JdkRegexpMethodPointcut、org.springframework.aop.support.Perl5RegexpMethodPointcut,org.springframework.aop.support.ExpressionPointcut,这四种可以用来描述切入点的类均可由DefaultPointcutAdvisor来进行封装,首先我们讲解一下DefaultPointcutAdvisor的使用方法:

   DefaultPointcutAdvisor类的使用很简单,他有一个 advice及 pointcut 属性,advice属性用来指明要使用的通知,pointcut属性用来指定切入点,我们可以通过构造子或设值注入方式来配置这个 Bean。看下面的构造子注入方式:
   
< bean  id ="defaultAdvisor"  
   class
="org.springframework.aop.support.DefaultPointcutAdvisor" >  
   
< constructor-arg  ref ="adviceBean" />  
   
< constructor-arg  ref ="poingcutBean" />  
  
</ bean >  
或者使用设值方法注入,如下所示:
< bean  id ="defaultAdvisor"  
   class
="org.springframework.aop.support.DefaultPointcutAdvisor" >  
   
< property  name ="advice"  ref ="adviceBean" ></ property >  
   
< property  name ="pointcut"  ref ="pointcutBean" ></ property >  
 
</ bean >
 
下面集合这四种切入点的描述类一起讲解 DefaultPointcutAdvisor:
1、 org.springframework.aop.support.NameMatchMethodPointcut
   将前面的 RegexpMethodPointcutAdvisor的配置换成NameMatchMethodPointcut结合DefaultPointcutAdvisor只需要修改配置文件,最终配置如下:
 
<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
    
< bean  id ="beforeAdvice"
       class
="spring.chapter3.advice.AdviceBeforeComponent"   />
    
< bean  id ="component"  class ="spring.chapter3.proxy.Component"   />
< bean  id ="pointcutBean"  class ="org.springframework.aop.support.NameMatchMethodPointcut" >
    
< property  name ="mappedNames" >  
    
< list >  
     
< value > business* </ value >  
      
</ list >  
   
</ property >  
</ bean >
    
< bean  id ="defaultAdvisor"        class ="org.springframework.aop.support.DefaultPointcutAdvisor" >
       
< property  name ="advice"  ref =" beforeAdvice " />
       
< property  name ="pointcut"  ref ="pointcutBean"   />
    
</ bean >
    
< bean  id ="proxy"
       class
="org.springframework.aop.framework.ProxyFactoryBean" >
       
< property  name ="proxyInterfaces"
           value
="spring.chapter3.proxy.IComponent"   />
       
< property  name ="target"  ref ="component"   />
       
< property  name ="interceptorNames" >
           
< list >
              
< value > defaultAdvisor </ value >
           
</ list >
       
</ property >
    
</ bean >
</ beans >
NameMatchMethodPointcut只有一个属性 mappedName或者mappedNames,前者表示映射单个字符串,后者表示映射一组字符串,支持<list>配置,这里“business*”表示所有business开头的方法,这里的“*”是通配符不是正则表达式,可以看出DefaultPointcutAdvisor的配置也很简单,就是给advice属性指定为beforeAdvice也就是前置通知,同时给pointcut属性指向了配置的NameMatchMethodPointcut。
2、org.springframework.aop.support.JdkRegexpMethodPointcut、
   org.springframework.aop.support.Perl5RegexpMethodPointcut
   由于这2个都是正则表达式切入点的描述,所以这里就放到一起对比讲解,JdkRegexpMethodPointcut需要在 JDK1.4 及以上的环境运行,不需要额外的库;Perl5RegexpMethodPointcut需要把 jakarta-oro-xx.jar 文件放到 classpath 上,比如 jakarta-oro-2.0.8.jar,这2个正则表达式切入点描述类的使用方法一样,他们均有2个属性:
 (1) pattern或patterns:前者表示单个正则表达式,后置表示多个正则表达式,支持<list>配置;
 (2) ExcludedPattern或ExcludedPatterns:前者表示排除某个字符串,后者表示排除一组字符串,支持<list>配置;
 根据上面的讲述我们将前面的NameMatchMethodPoint改成JdkRegexpMethodPointcut和Perl5RegexpMethodPointcut配置,分别如下:
   JdkRegexpMethodPointcut配置:
  
  ...
< bean  id ="pointcutBean"
class
="org.springframework.aop.support. JdkRegexpMethodPointcut" >
    
< property  name ="pattern" >  
         
< value > .*business.* </ value >  
      
</ property >  
     
< property  name ="ExcludedPattern" >  
         
< value > business2 </ value >  
      
</ property >
</ bean >
    ...
   这里表示匹配所有 business 开头的方法但是除去了 business2 这个方法,其他的配置和 NameMatchMethodPointcut 一样。
 Perl5RegexpMethodPointcut配置:
    
...
< bean  id ="pointcutBean"
class
="org.springframework.aop.support. Perl5RegexpMethodPointcut" >
    
< property  name ="pattern" >  
         
< value > .*business.* </ value >  
      
</ property >  
     
< property  name ="ExcludedPattern" >  
         
< value > business2 </ value >  
      
</ property >
</ bean >
    ...
这里只需要给class换成 org.springframework.aop.support. Perl5RegexpMethodPointcut就可以了,同时在classpath中要添加jakarta-oro-xx.jar文件,其他的不需要做任何改变。
3、org.springframework.aop.support.ExpressionPointcut
   在 Spring2 中,在 Pointcut 的基础上,引入了一个 ExpressionPointcut 接口用来通过切入点表达语言来描述切入点。有了 ExpressionPointcut,我们可以使用下面更加简单的方式来描述切入点,如 execution(* Component.business*(..))表示执行所有 Component 的业务方法(此处为 business 打头的方法)。
 Spring2 提供了一个 ExpressionPointcut 的实现,即 AspectJExpressionPointcut,该类的使用很简单,只需要做如下配置即可:
...
   
< bean  id ="pointcutBean"  
class
="org.springframework.aop.aspectj.AspectJExpressionPointcut" >
 
< property  name ="expression"  
    value
="execution(void spring.chapter3.proxy.Component.business*(..))" >  
   
</ property >  
 
</ bean >
...
其他的配置和前面的几个均一样。
除了以上4种不同的切入点的应用,还可以自定义切入点进行某些特殊的运用,自定义切入点类只需要实现org.springframework.aop.pointcut类,然后再bean中声明该类,接着就可以使用这些自定的pointcut类了。

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
是的,`ComboPooledDataSource`类并没有`readOnly`属性。如果你想在Hibernate使用只读模式,你可以通过配置一个拦截器来实现。 首先,在Spring配置文件,你需要声明一个`SessionFactory` bean,并将一个`HibernateTransactionManager` bean与之关联。然后,你需要将一个`ReadOnlyInterceptor` bean与`SessionFactory`关联。 下面是配置文件的示例: ```xml <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 数据源配置 --> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>com.example.domain</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="readOnlyInterceptor" class="com.example.interceptor.ReadOnlyInterceptor" /> <bean id="defaultAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice"> <bean class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,-Throwable</prop> </props> </property> </bean> </property> <property name="pointcut"> <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="patterns"> <list> <value>com.example.service.*</value> </list> </property> </bean> </property> </bean> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <list> <value>readOnlyInterceptor</value> </list> </property> </bean> ``` 在上面的配置文件,我们声明了一个名为`readOnlyInterceptor`的拦截器,并将其与`SessionFactory` bean关联。然后,我们使用`BeanNameAutoProxyCreator` bean将此拦截器应用于所有以`*Service`结尾的bean。 下面是`ReadOnlyInterceptor`类的示例实现: ```java public class ReadOnlyInterceptor extends EmptyInterceptor { @Override public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { throw new UnsupportedOperationException("Delete operation is not allowed in read-only mode."); } @Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { throw new UnsupportedOperationException("Update operation is not allowed in read-only mode."); } @Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { throw new UnsupportedOperationException("Insert operation is not allowed in read-only mode."); } @Override public void preFlush(Iterator entities) { throw new UnsupportedOperationException("Flush operation is not allowed in read-only mode."); } @Override public void postFlush(Iterator entities) { // Do nothing } } ``` 在上面的实现,我们覆盖了`EmptyInterceptor`的一些方法,其包括`onDelete`、`onFlushDirty`、`onSave`和`preFlush`,并在这些方法抛出了不支持的操作异常。这样,当Hibernate尝试执行这些操作时,它将抛出异常并停止执行。 最后,只需将`readOnlyInterceptor` bean声明为一个Spring组件,并在配置文件引用它即可。 希望这可以帮助你解决问题!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值