4
springboot~为接口添加动态代理
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.
为接口添加动态代理,不需要添加接口实现,通过定义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();
}
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK