问题
在Spring注解注入的基础上实现自定义的类注册,手动向Spring上下文注册我们自定义的Bean,和Spring自己注册的Bean同样效果
方式一:
如果使用普通Spring.xml配置的方式可以自己配置,这里不做解释,不过我用的是Springboot,这个方法直接pass
方式二:
BeanDefinitionRegistryPostProcessor的方式,采用自定义注解,给Class打打注解标记,也达不到我想要的效果,我的bean是继承某个类而不是注解,也pass。
不过根据方式二总算研究出一个全面的方法。
主要实现思路:
1、BeanDefinitionRegistryPostProcessor作为Spring预留的Bean注入接口类
2、自己手动扫描指定包(或子包)下的所有Class,并在1中预留的接口注入我的Bean。
BeanDefinitionRegistryPostProcessor好理解,百度一下就知道怎么使用。关键2中的扫描比较复杂(主要我的要求比较不同),如何扫描到自己的想要的类了?
关键用到:
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner配合BeanDefinitionRegistryPostProcessor可以完成Spring默认的一些注解注入的注册。但我的并没有使用Spring提供任何注解。一直扫描为0.
查找源码,在他的父类找到
![](https://osswb.oss-cn-shanghai.aliyuncs.com/image/846d39d6-438a-4ea5-9e86-82a0a96f754e.jpg)
Type过滤器集,一个是包含,另一个是排除。我这里只需要一个包含就就好。
继续找,一个公共注册过滤器的接口出现了。不错!
. public void addIncludeFilter(TypeFilter includeFilter) {
this.includeFilters.add(includeFilter);
}
看来实现的外在条件都存在了,那就开始码代码了。
直接上代码:
package ****;
import ****.Control;
import ****.Screen;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
@Configuration
public class BeanDefinitionRegistryConfig implements BeanDefinitionRegistryPostProcessor {
public static final String SCREEN_PREFIX = "screen";
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
String aPackage = this.getClass().getPackage().getName();
int i = registryScreen(aPackage), beanDefinitionRegistry);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
private int registryScreen(String basePackage, BeanDefinitionRegistry beanDefinitionRegistry) {
ClassPathBeanDefinitionScanner classPathBeanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);
classPathBeanDefinitionScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
if (metadataReader.getClassMetadata().getSuperClassName().equals(Screen.class.getName())) {
return true;
}
return false;
}
});
classPathBeanDefinitionScanner.setBeanNameGenerator(new BeanNameGenerator() {
@Override
public String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
String beanClassName = beanDefinition.getBeanClassName();
String s = beanClassName.replaceAll(basePackage, SCREEN_PREFIX);
return s.toLowerCase();
}
});
return classPathBeanDefinitionScanner.scan(basePackage);
}
}
尊重作者,转载请注明出处!
版权申明:本文版权归作者所有,未经授权,任何单位或个人不得以任何形式转载、摘编或利用其它方式使用本博客内容。作者保留追究相关法律责任的权利。如需使用博客内容,请与作者联系获得授权。感谢对本文的尊重与支持。
免责声明:本网站所载内容仅供参考,不构成任何专业建议。用户基于本网站内容作出的决策,风险自担。对于因使用本网站内容而产生的任何直接或间接损失,本网站不承担任何责任。请用户审慎判断,理性使用。