版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012727852/article/details/82800599
思路:
- 实现BeanFactoryPostProcessor接口、ResourceLoaderAware接口。
- 在实现类中定义MetadataReaderFactory、ResourcePatternResolver变量。
- 在ResourceLoaderAware接口的setResourceLoader方法中使用SimpleMetadataReaderFactory和ResourcePatternUtils.getResourcePatternResolver分别初始化步骤【2】中的2个变量。
- 在BeanFactoryPostProcessor的postProcessBeanFactory中实现业务逻辑。
- 根据自己的需要的信息来过滤类元素信息。
- 通过resourcePatternResolver.getResources(locationPattern)获取所有Resource列表。
- 通过metadataReaderFactory.getMetadataReader(classResource)获取MetadataReader,metadataReader.getClassMetadata()可以获取类的元数据信息。
示例代码:
/**
* @description: 把rpc服务发布成SpringBean的注册器,实现服务本地化,使用者只需要把接口@Autowired即可
* @author: gongqi
* @create: 2018/09/10 11:46
*/
public class RpcToSpringBeanRegister implements BeanFactoryPostProcessor, ResourceLoaderAware {
private static final Logger logger = LoggerFactory.getLogger(RpcToSpringBeanRegister.class);
//
protected MetadataReaderFactory metadataReaderFactory;
protected ResourcePatternResolver resourcePatternResolver;
private String packageToScan;
public RpcToSpringBeanRegister(String packageToScan){
this.packageToScan=packageToScan;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
//获取所有的资源文件
Resource[] classResources = resourcePatternResolver.getResources(getLocationPattern());
for (Resource classResource : classResources) {
//
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classResource);
String className = metadataReader.getClassMetadata().getClassName();
Class<?> clazz = ClassUtils.forName(className, beanFactory.getBeanClassLoader());
//如果接口上加了@CloudService注解则把接口发布成代理
if (AnnotationUtils.isAnnotationDeclaredLocally(CloudService.class, clazz)) {
String serviceName = getServiceName(clazz);
Object serviceProxy = getServiceProxy(clazz, beanFactory);
Assert.notNull(serviceName, "'beanName' must not be null");
if(null==beanFactory.getSingleton(serviceName)) {
logger.info("正在注册rpc服务到spring上下文:"+serviceName);
beanFactory.registerSingleton(serviceName, serviceProxy);
}
}
}
} catch (Exception e) {
throw new FatalBeanException(e.getMessage(), e);
}
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.metadataReaderFactory = new SimpleMetadataReaderFactory(resourceLoader);
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
}
/**
* 获取服务的代理对象
* @param serviceClass
* @param beanFactory
* @return
*/
protected Object getServiceProxy(Class<?> serviceClass, ConfigurableListableBeanFactory beanFactory) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addInterface(serviceClass);
//
//生成拦截器
RpcInvokeInterceptor invokeInterceptor=new RpcInvokeInterceptor(serviceClass);
//
proxyFactory.addAdvice(invokeInterceptor);
return proxyFactory.getProxy(beanFactory.getBeanClassLoader());
}
/**
* 获取资源的路径
* @return
*/
protected String getLocationPattern() {
return ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(packageToScan) + "/**/*.class";
}
/**
* spring ByName方式注入的名称
* @param serviceClass
* @return
*/
protected String getServiceName(Class<?> serviceClass) {
return StringUtils.uncapitalize(serviceClass.getSimpleName());
}
}
BeanFactoryPostProcessor、ResourceLoaderAware、MetadataReaderFactory、ResourcePatternResolver的作用介绍请参照【spring学习里】的对应的帖子。