springboot~為接口添加動態代(dai)理(li)
為接(jie)口添加動態代理(li),不(bu)需要添加接(jie)口實(shi)現(xian),通過定義(yi)FactoryBean的方式實(shi)現(xian),將自(zi)定義(yi)業務在InvocationHandler接(jie)口實(shi)現(xian)即可(ke)
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar注入FactoryBean到SpringIOC中,而在FactoryBean中定義了類型T的動態代理,通過對InvocationHandler接口
的(de)實現來添加自定義行為,這里使用jdk默認的(de)代理,只支持接(jie)口類型。
使用場景
當(dang)需要為某個接口動(dong)態添加一(yi)種(zhong)行為時,不需要建立它(ta)的實現(xian)類,可以通過動(dong)態代(dai)(dai)理(li)去(qu)建立它(ta)的實現(xian)類,在代(dai)(dai)理(li)中添加自定義的邏輯。
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();
}
}
結果
