• 《Spring》(十六)---- 基于Schema的AOP


    要使用基于Schema的AOP,IoC容器的配置文件应该使用基于Schema的XML,同时在文件投中增加针对AOP的命名空间声明,如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/aop
                                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
        
        <!--相关bean定义-->
    </bean>

    新的基于Schema的AOP配置方式,针对Pointcut,Advisor以及Aspect等概念提供了独立的配置元素。所有这些配置元素都包含在统一的配置元素中,即<aop:config>, <aop:config> 只有一个属性proxy-target-class, 对应ProxyConfig中的proxyTargetClass属性,通过该属性可以控制使用基于类还是基于接口的动态代理。如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/aop
                                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
        
        <aop:config proxy-target-class="true">
            <!--其他aop概念元素定义-->
        </aop:config>    
        
        
    </beans>

      <aop:config>内部可以有三个子元素,分别是<aop:pointcut>,<aop:advisor>和<aop:aspect>。它们三个必须按照顺序进行配置,代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/aop
                                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
        
        <aop:config proxy-target-class="false">
            <aop:pointcut/>
                    <aop:advisor/>
                    <aop:aspect></aop:aspect>
        </aop:config>    
        
        
    </beans>

      另外,可以在同一个配置文件中配置多个<aop:config>.

      <aop:config> 会根据元素内部对应的Pointcut,Advisor以及Aspect的子元素取得必要的织入信息,然后为容器内注册的bean进行自动代理。和使用AutoProxyCreator一样。但两者最好不要混用。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/aop
                                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
        
        <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods"> // 1
                <aop:before method="preGreeting" pointcut="target(com.ivy.NaiveWaiter) and execution(* greetTo(..))"/> // 2
            </aop:aspect>
        </aop:config>    
        
        <bean id="adviceMethods" class="com.ivy.schema.AdviceMethods"/> // 3
        <bean id="naiveWaiter" class="com.ivy.NaiveWaiter"/>
        <bean id="naughtWaiter" class="com.ivy.NaughtyWaiter"/>
    </beans>

      

      使用一个<aop:aspect>元素标签定义切面,其内部可以定义多个增强。在<aop:config>元素中可以定义多个切面。在1处,切面引用了adviceMethods Bean, 该Bean是增强方法所在的类。通过<aop:before> 声明了一个前置增强,并通过pointcut属性定义切点表达式,method属性指定增强的方法,该方法应该是adviceMethods bean中的方法。

      <aop:config>拥有一个proxy-target-class属性,当设置为true时,表示其中声明的切面均使用CGLib动态代理技术;当设置为false时,使用JDK动态代理。一个配置文件可以同时定义多个<aop:config>,不同的<aop:config>可以采取不同的代理技术。

       

      1, 基于Schema的Aspect声明

    <aop:config>
        <aop:aspect id="myAspect" ref="schemaBasedAspect" order="2">
             ...
        </aop:aspect>
    </aop:config>

      2, 基于Schema的Pointcut声明

      基于Schema的Pointcut声明(<aop:pointcut〉)可以位于两个位置:一个位置是直接声明到<aop:config>下面,这样的Pointcut定义可以在其余的Advisor定义和Aspect定义中共享引用,另一个位置就是<aop:aspect>元素内部,这种Pointcut只能在其所声明的<aop:aspect〉内部引用,相当于修饰符是private。

    <aop:config>
        <aop:aspect id="myAspect" ref="schemaBasedAspect" order="2">
             <aop:pointcut id="privatePointcut" expression="execution(public void *.doSth())" />
             ...
        </aop:aspect>
    </aop:config>
    <bean id="shemaBasedAspect" class="...SchemaBasedAspect"></bean>

      3, 基于Schema的Advice声明

      在基于Schema的AOP中的Advice声明也分为两部分,Advice定义和Advice到容器中的配置。

      

    配置命名切点

      上例2处通过pointcut属性声明的切点是匿名切点,它不能被其他增强或其他切面使用,Spring提供了命名切点的配置方式:

    <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
              <aop:pointcut expression="target(com.ivy.NaiveWaiter)" id="greetToPointcut"/>
                <aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
            </aop:aspect>
        </aop:config>    

      <aop:pointcut>如果位于<aop:aspect>元素中,则命名切点只能被当前<aop:aspect>内定义的元素访问到,为了能被整个<aop:config>元素中定义的所有增强访问,则必须在<aop:config>下定义切点,且必须保证<aop:pointcut>在<aop:aspect>之前定义:

    <aop:config proxy-target-class="true">
            <aop:pointcut expression="target(com.ivy.NaiveWaiter)" id="greetToPointcut"/>
            <aop:aspect ref="adviceMethods">
                <aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
            </aop:aspect>
            
            <aop:aspect ref="adviceMethods">
                <aop:after method="preGreeting" pointcut-ref="greetToPointcut"/>
            </aop:aspect>
        </aop:config>    

      各类增强配置

    1. 后置增强
        <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
                <aop:after-returning method="afterReturning" pointcut="target(com.ivy.Seller)" returning="retVal"/>
            </aop:aspect>
        </aop:config>    

    增强对应方法:

    public void afterReturning(int retVal) {
            // 增强方法,retVal和配置文件中的returning属性值相同
        }

    如果增强不希望接收返回值,就把returning属性和增强方法的对应入参去掉即可。

      2. 环绕增强

    <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
                <aop:around method="aroundMethod" pointcut="execution(* serveTo(..) and within(com.ivy.Waiter))"/>
            </aop:aspect>
        </aop:config>

      3. 抛出异常增强

    <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
                <aop:after-throwing method="afterThrowingMethod" pointcut="target(com.ivy.Seller) and execution(* checkBill(..))" throwing="iae"/>
            </aop:aspect>
        </aop:config>
    public void afterThrowingMethod(IllegalArgumentException iae) {
            
        }

      4. Final增强

    <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
                <aop:after method="afterMethod" pointcut="execution(* com..*.Waiter.greetTo(..))"/>
            </aop:aspect>
        </aop:config>

      5. 引介增强

        <aop:config proxy-target-class="true">
            <aop:aspect ref="adviceMethods">
                <aop:declare-parents types-matching="com.ivy.Waiter+" implement-interface="com.ivy.Seller" default-impl="com.ivy.SmartSeller"/>
            </aop:aspect>
        </aop:config>

      <aop:declare-parents>通过implement-interfaces属性声明要实现的接口,通过default-impl属性指定默认的接口实现,然后通过type-matching属性以切点表达式语法指定哪些bean需要引介Seller接口的实现。

      

  • 相关阅读:
    Photoshop 基础七 位图 矢量图 栅格化
    Photoshop 基础六 图层
    Warfare And Logistics UVALive
    Walk Through the Forest UVA
    Airport Express UVA
    Guess UVALive
    Play on Words UVA
    The Necklace UVA
    Food Delivery ZOJ
    Brackets Sequence POJ
  • 原文地址:https://www.cnblogs.com/IvySue/p/6589140.html
Copyright © 2020-2023  润新知