4

springboot~为接口添加动态代理

 2 years ago
source link: https://www.cnblogs.com/lori/p/15877837.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

为接口添加动态代理,不需要添加接口实现,通过定义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();
  }
}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK