springboot~為接口添加動態代理


為接口添加動態代理,不需要添加接口實現,通過定義FactoryBean的方式實現,將自定義業務在InvocationHandler接口實現即可

ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrar注入FactoryBean到SpringIOC中,而在FactoryBean中定義了類型T的動態代理,通過對InvocationHandler接口
的實現來添加自定義行為,這里使用jdk默認的代理,只支持接口類型。

使用場景

當需要為某個接口動態添加一種行為時,不需要建立它的實現類,可以通過動態代理去建立它的實現類,在代理中添加自定義的邏輯。

RunFactoryBean

public class RunFactoryBean<T> implements FactoryBean<T> {
  private Class<T> interfaceType;

  public Class<T> getInterfaceType() {
    return interfaceType;
  }

  public void setInterfaceType(Class<T> interfaceType) {
    this.interfaceType = interfaceType;
  }

  @Override
  public T getObject() throws Exception {
    InvocationHandler handler = (proxy, method, args) -> {
      System.out.println("代理T類型做一些事情");
      return null;
    };
    return (T) Proxy.newProxyInstance(interfaceType.getClassLoader(),
        new Class[]{interfaceType}, handler);
  }

  @Override
  public Class<?> getObjectType() {
    return interfaceType;
  }

RunFactoryBeanDefinitionRegistry

public class RunFactoryBeanDefinitionRegistry implements ImportBeanDefinitionRegistrar {
  @SneakyThrows
  @Override
  public void registerBeanDefinitions(AnnotationMetadata annotationMetadata,
                                      BeanDefinitionRegistry beanDefinitionRegistry) {
    Class beanClazz= Demo.Bird.class;
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClazz);
    GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();

    MutablePropertyValues propertyValues = definition.getPropertyValues();
    propertyValues.add("interfaceType", beanClazz);
    definition.setBeanClass(RunFactoryBean.class);
    definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
    beanDefinitionRegistry.registerBeanDefinition(beanClazz.getSimpleName(), definition);
  }
}

unit test

@Import({RunFactoryBeanDefinitionRegistry.class})
public class Demo {
  @Test
  public void run() {
    ApplicationContext applicationContext=new AnnotationConfigApplicationContext(Demo.class);
    Bird bird= applicationContext.getBean(Bird.class);
    bird.run();
  }

  interface Bird {
    void run();
  }
}

結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM