• SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-010-Introduction为类增加新方法@DeclareParents、<aop:declare-parents>


    一、

    1.Introduction的作用是给类动态的增加方法

    When Spring discovers a bean annotated with @Aspect , it will automatically create a proxy that delegates calls to either the proxied bean or to the introduction implementation, depending on whether the method called belongs to the proxied bean or to the introduced interface.

    二、例子

    要为演出者增加encore功能

    1.

    package concert;
    
    public interface Performance {
      void performance();
    }

    2.

     1 package concert;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 public class Eminem implements Performance{
     7 
     8     @Override
     9     public void performance() {
    10         System.out.println("you can do anything set to your mind");
    11     }
    12 
    13 }

    3.

    package concert;
    
    public interface Encoreable {
        void performEncore();
    }

    4.

     1 package concert;
     2 
     3 public class DefaultEncoreable implements Encoreable{
     4 
     5     @Override
     6     public void performEncore() {
     7         System.out.println("DefaultEncoreable---> performEncore()");
     8     }
     9 
    10 }

    5.

     1 package concert;
     2 
     3 import org.aspectj.lang.annotation.Aspect;
     4 import org.aspectj.lang.annotation.DeclareParents;
     5 import org.springframework.stereotype.Component;
     6 
     7 @Aspect
     8 @Component
     9 public class EncoreableIntroducer {
    10     @DeclareParents(value = "concert.Performance+", defaultImpl = DefaultEncoreable.class)
    11     public static Encoreable encoreable;
    12 }

    解析:

     @DeclareParents的作用是把"Encoreable"介绍给"Performance",它由三部分组成

    (1)value:要增加新功能的bean的接口类型

    (2)defaultImpl:要增加的功能接口的实现

    (3)增加的功能接口的静态变量

    6.配置文件

    package concert;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @Configuration
    @ComponentScan
    @EnableAspectJAutoProxy
    public class Config {
    
    }

    7.测试

     1 import org.junit.Test;
     2 import org.junit.runner.RunWith;
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.test.context.ContextConfiguration;
     6 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     7 
     8 import concert.Config;
     9 import concert.Encoreable;
    10 
    11 @RunWith(SpringJUnit4ClassRunner.class)
    12 @ContextConfiguration(classes=Config.class)
    13 public class IntroductionTest {
    14   @Autowired
    15   ApplicationContext context;
    16 
    17   @Test
    18   public void eddieShouldBeAContestant() {
    19     Encoreable eminem = (Encoreable) context.getBean("eminem");
    20     eminem.performEncore();
    21 //      Performance eminem = (Performance) context.getBean("eminem");
    22 //      eminem.performance();
    23   }
    24 }

    另外:xml的配置方法:

    1 <aop:aspect>
    2     <aop:declare-parents types-matching="concert.Performance+" implement-interface="concert.Encoreable" default-impl="concert.DefaultEncoreable" />
    3 </aop:aspect>

    As its name implies, <aop:declare-parents> declares that the beans it advises will have new parents in its object hierarchy. Specifically, in this case you’re saying that the beans whose type matches the Performance interface (per the types-matching attribute) should have Encoreable in their parentage (per the implement-interface attribute). The final matter to settle is where the implementation of the Encoreable ’s methods will come from.

    还有另一个指定方法用delegate-ref属性

    <aop:aspect>
        <aop:declare-parents types-matching="concert.Performance+" implement-interface="concert.Encoreable" delegate-ref="encoreableDelegate" />
    </aop:aspect>

    The delegate-ref attribute refers to a Spring bean as the introduction delegate.This assumes that a bean with an ID of encoreableDelegate exists in the Spring context:

    <bean id="encoreableDelegate" class="concert.DefaultEncoreable" />

    The difference between directly identifying the delegate using default-impl and indirectly using delegate-ref is that the latter will be a Spring bean that itself may be injected, advised, or otherwise configured through Spring.

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4  xmlns:aop="http://www.springframework.org/schema/aop"
     5  xsi:schemaLocation="http://www.springframework.org/schema/beans 
     6      http://www.springframework.org/schema/beans/spring-beans.xsd
     7      http://www.springframework.org/schema/aop
     8      http://www.springframework.org/schema/aop/spring-aop.xsd">
     9 
    10   <bean id="eddie"
    11       class="com.springinaction.springidol.Instrumentalist">
    12     <property name="instrument">
    13       <bean class="com.springinaction.springidol.Guitar" />
    14     </property>
    15   </bean>
    16 
    17   <!--<start id="audience_bean"/>--> 
    18   <bean id="audience" 
    19       class="com.springinaction.springidol.Audience" />
    20   <!--<end id="audience_bean"/>-->
    21 
    22   <!--<start id="audience_aspect"/>--> 
    23   <aop:config>
    24     <aop:aspect ref="audience">
    25       <aop:pointcut id="performance" expression=
    26         "execution(* com.springinaction.springidol.Performer.perform(..))" 
    27       /> 
    28       <aop:before 
    29           pointcut-ref="performance"
    30           method="takeSeats()" />
    31       <aop:before 
    32           pointcut-ref="performance"
    33           method="turnOffCellPhones" />
    34       <aop:after-returning
    35           pointcut-ref="performance"
    36           method="applaud" />
    37       <aop:after-throwing 
    38           pointcut-ref="performance"
    39           method="demandRefund" />
    40     </aop:aspect>
    41     
    42     <!--<start id="contestant_introduction"/>--> 
    43 <aop:aspect>
    44   <aop:declare-parents 
    45     types-matching="com.springinaction.springidol.Performer+" 
    46     implement-interface="com.springinaction.springidol.Contestant"
    47     default-impl="com.springinaction.springidol.GraciousContestant"
    48     />
    49 </aop:aspect>
    50     <!--<end id="contestant_introduction"/>-->
    51 
    52     <!--
    53 <start id="delegate_ref"/>    
    54 <aop:declare-parents 
    55   types-matching="com.springinaction.springidol.Performer+" 
    56   implement-interface="com.springinaction.springidol.Contestant"
    57   delegate-ref="contestantDelegate"
    58   />
    59     <end id="delegate_ref"/>   
    60 
    61 <start id="contestant_delegate"/>    
    62 <bean id="contestantDelegate"
    63     class="com.springinaction.springidol.GraciousContestant" />
    64     <end id="contestant_delegate"/>   
    65 
    66      -->
    67     
    68   </aop:config>
    69   <!--<end id="audience_aspect" />-->
    70 
    71 </beans>
  • 相关阅读:
    基于mave的dubbo分别架构
    海西 · 云交付 DevOps实践落地方案
    LoadRunner接口测试标准模板
    SVN多分支开发模式V1.0.1
    API接口规范V1.0——制定好规范,才好合作开发
    Effective Java 第三版——12. 始终重写 toString 方法
    Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
    Effective Java 第三版——10. 重写equals方法时遵守通用约定
    Effective Java 第三版——9. 使用try-with-resources语句替代try-finally语句
    Effective Java 第三版——8. 避免使用Finalizer和Cleaner机制
  • 原文地址:https://www.cnblogs.com/shamgod/p/5240348.html
Copyright © 2020-2023  润新知