如何在BeanDefinitionRegistryPostProcessor中注册未存在的指定接口实现类Bean
实现
isAlreadyRegistered方法的思路 要检查是否已有实现SpecialInterface的Bean注册,核心是通过BeanDefinition解析出对应的Class类型,再判断该类型是否实现目标接口。具体实现步骤如下:
遍历所有已注册的BeanDefinition名称
调用registry.getBeanDefinitionNames()获取所有已注册的Bean名称,逐个处理每个BeanDefinition。解析BeanDefinition对应的Class类型
Spring的BeanDefinition提供了resolveBeanClass()方法,传入当前上下文的ClassLoader就能解析出实际的Class对象。需要注意处理ClassNotFoundException,避免因类未加载导致的异常。判断Class是否实现目标接口
利用Class.isAssignableFrom()方法,检查目标接口是否是该Class的父接口(包括直接实现和间接实现);或者直接遍历Class.getInterfaces()数组,检查是否包含目标接口。
下面是具体的代码实现:
protected boolean isAlreadyRegistered(Class<?> clazz, BeanDefinitionRegistry registry) { // 获取所有已注册的Bean名称 String[] beanNames = registry.getBeanDefinitionNames(); // 获取当前上下文的类加载器 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); for (String beanName : beanNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); Class<?> beanClass = null; try { // 解析BeanDefinition对应的Class beanClass = beanDef.resolveBeanClass(classLoader); } catch (ClassNotFoundException e) { // 若类未加载,跳过该BeanDefinition的检查 continue; } // 检查当前Bean的Class是否实现了目标接口 if (beanClass != null && clazz.isAssignableFrom(beanClass)) { return true; } } return false; }
补充说明
- 如果遇到
FactoryBean类型的Bean,上述代码检查的是FactoryBean本身的类型,若要检查FactoryBean生成的Bean类型,需要额外处理:判断beanClass是否实现了FactoryBean接口,然后通过FactoryBean.getObjectType()方法获取实际Bean的类型再检查。 - 对于延迟加载的BeanDefinition,
resolveBeanClass()会触发类加载,若不想触发加载,可以尝试从BeanDefinition的beanClassName属性获取类名,再通过ClassLoader加载类,但这种方式同样会触发类加载,本质和resolveBeanClass()一致。
内容的提问来源于stack exchange,提问作者Darien
相关产品推荐
相关产品推荐

