Spring API级别对AOP的支持

在Spring 2.0之前,Spring通过定义一套接口和通过ProxyFactoryBean来生产bean实例提供对AOP的支持,在2.0后,Spring推荐通过AspectJ兼容的方式来实现AOP.见http://blog.csdn.net/kkdelta/archive/2010/04/22/5515882.aspx
1,定义'方面'拦截器,最常用的接口有:
MethodInterceptor: 在方法执行的前后执行,相当于2.0的@Around.
MethodBeforeAdvice:在方法执行前执行,相当于2.0的@Before.
ThrowsAdvice :在方法异常后执行,相当于2.0的@AfterThrowing.
AfterReturningAdvice :在方法执行后执行,相当于2.0的@AfterReturning.
2,配置ProxyFactoryBean,使用ProxyFactoryBean创建AOP代理.最常用的配置项:
proxyInterfaces : 需要代理的接口名的字符串数组。如果没有提供,将为目标类使用一个CGLIB代理.
interceptorNames:Advisor的字符串数组,可以包括拦截器或其它advice的名字。顺序是很重要的,排在前面的将被优先服务。就是说列表里的第一个拦截器将能够第一个拦截调用。(Advisor是一个advice,在某些特定规则的方法执行的时候被触发)
target : 指定你希望代理的目标对象.
例子:
1,POJO bean类:
public interface IHelloWorld {
    public String getContent(String helloworld);
    public String testExp(String exp);
}
public interface IHelloWorld2 {
    public String testExp2(String exp);
}
public class HelloWorld implements IHelloWorld,IHelloWorld2 {
    protected static final Log log = LogFactory.getLog(HelloWorld.class);
    public String getContent(String helloworld) {
        log.info(helloworld);
        return helloworld;
    }  
    public String testExp(String exp){
        log.info(exp);
        return exp;
    }  
    public String testExp2(String exp){
        log.info("testExp2 " + exp);
        return exp;
    }
}
advice 类:
public class LoggingBeforeAdvice implements  MethodBeforeAdvice {
    protected static final Log log = LogFactory.getLog(LoggingBeforeAdvice.class);
    public void before(Method m, Object[] args, Object target) throws Throwable {
        log.info("before: The Invocation The Invocation of " + m.getName());
    }
}
public class LoggingAfterAdvice implements AfterReturningAdvice {
    protected static final Log log = LogFactory.getLog(LoggingAfterAdvice.class);

    public void afterReturning(Object object, Method m, Object[] args,
        Object target) throws Throwable {
        log.info("after: The Invocation of " + m.getName());    
    }
}
public class DebugInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: invocation=[" + invocation + "]");
        Object rval = invocation.proceed();
        System.out.println("Invocation returned");
        return rval;
    }
}
配置文件:
<beans>
    <bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <list>
                <value>com.test.spring.aop.api.IHelloWorld</value>
                <value>com.test.spring.aop.api.IHelloWorld2</value>
            </list>
        </property>
        <property name="target">
            <ref local="helloworldbeanTarget" />
        </property>
        <property name="interceptorNames">
            <list>
                <value>loggingBeforeAdvice</value>
                <value>debugInterceptor</value>
            </list>
        </property>
    </bean>
    <bean id="helloworldbeanTarget" class="com.test.spring.aop.api.HelloWorld" />
    <bean id="loggingAfterAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice">
                <ref local="loggingAfterAdvice" />
        </property>
        <property name="pattern">
            <value>.*</value>
        </property>
    </bean>
    <bean id="loggingBeforeAdvice" class="com.test.spring.aop.api.LoggingBeforeAdvice" />
    <bean id="loggingAfterAdvice" class="com.test.spring.aop.api.LoggingAfterAdvice" />
    <bean id="debugInterceptor" class="com.test.spring.aop.api.DebugInterceptor" />
</beans>
调用代码:
       ApplicationContext context = new ClassPathXmlApplicationContext("conf/aopapiAppcontext1.xml");
        IHelloWorld bean = (IHelloWorld) context.getBean("helloworldbean");
        try {
            bean.getContent("helloworld");         
            bean.testExp("test RegexpMethodPointcutAdvisor");          
            IHelloWorld2 bean2 = (IHelloWorld2)bean;       
            bean2.testExp2("2 test RegexpMethodPointcutAdvisor");         
        } catch (Exception e) {
        }
一种较好的方法是对某一类bean设置相同的切面设置,如下:
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
      <property name="beanNames"><value>hello*</value></property>
      <property name="proxyTargetClass" value="true"/>
      <property name="interceptorNames">
        <list>
          <value>debugInterceptor</value>
        </list>
      </property>
    </bean>
    <bean id="helloworldbeanTarget" class="com.test.spring.aop.api.HelloWorld" />
    <bean id="debugInterceptor" class="com.test.spring.aop.api.DebugInterceptor" />
还可以定义一个模板bean,其他bean"继承"这个bean的定义,如事务管理
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/>
<bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager" ref="transactionManager"/>
  <property name="transactionAttributes">
    <props>
      <prop key="*">PROPAGATION_REQUIRED</prop>
    </props>
  </property>
</bean>
<bean id="myService1" parent="txProxyTemplate">
  <property name="target">
    <bean class="org.springframework.samples.MyServiceImpl1">
    </bean>
  </property>
</bean>
<bean id="myService2" parent="txProxyTemplate">
  <property name="target">
    <bean class="org.springframework.samples.MyServiceImpl2">
    </bean>
  </property>
</bean>
对于2.0以后配置事务管理则更为简单了
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"/>
    <aop:config>
        <aop:pointcut id="yyyProcessMethods" expression="execution(* com.xxx.yyy.*.*Processor.*(..))" />
        <aop:pointcut id="yyyProcessMethods" expression="execution(* com.xxx.yyy.srv.*service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="yyyProcessMethods" />
    </aop:config>
    <tx:advice id="txAdvice">
        <tx:attributes><tx:method name="*" propagation="REQUIRED" /></tx:attributes>
    </tx:advice>

你可能感兴趣的:(spring,AOP,bean,api,String,Class)