feat:仓库初始化问题修复

This commit is contained in:
wangyu 2021-12-08 10:54:09 +08:00
parent 6fc717a186
commit e5ae9766df
8 changed files with 142 additions and 50 deletions

View File

@ -4,6 +4,7 @@ import com.flyfish.framework.constant.Frameworks;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.util.CastUtils;
import reactor.core.publisher.Mono;
import java.util.Collections;
@ -143,6 +144,14 @@ public class Result<T> {
return (Result<R>) this;
}
public <R> Mono<Result<R>> flatMap(Function<T, Mono<R>> function) {
return Mono.defer(() -> function.apply(data))
.map(mapped -> {
this.data = CastUtils.cast(mapped);
return (Result<R>) this;
});
}
public Result<T> orElse(Result<T> other) {
if (null == this.data) {
return other;

View File

@ -1,5 +1,7 @@
package com.flyfish.framework.domain.base;
import reactor.core.publisher.Mono;
/**
* 基础的视图模型
*
@ -7,15 +9,27 @@ package com.flyfish.framework.domain.base;
*/
public interface Vo<T> {
void setId(String id);
String getId();
void setId(String id);
/**
* 赋值从po转换的逻辑
*
* @param po 数据库实体
* @return 结果
*/
Vo<T> from(T po);
default Vo<T> from(T po) {
return this;
}
/**
* 异步的进行查询处理
*
* @param po 实体
* @return 结果
*/
default Mono<Vo<T>> retrieve(T po) {
return Mono.just(from(po));
}
}

View File

@ -4,15 +4,11 @@ package com.flyfish.framework.dict.service;
import com.flyfish.framework.dict.domain.Dictionary;
import com.flyfish.framework.dict.repository.DictionaryRepository;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import com.flyfish.framework.utils.RedisOperations;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import com.flyfish.framework.utils.ReactiveRedisOperations;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.Optional;
/**
* 字典表服务
@ -25,9 +21,7 @@ public class DictionaryService extends BaseReactiveServiceImpl<Dictionary> {
private final String DICT_KEY = "dict-";
@Resource
private MongoOperations mongoOperations;
@Resource
private RedisOperations redisOperations;
private ReactiveRedisOperations reactiveRedisOperations;
/**
* 通过code查询
@ -35,29 +29,14 @@ public class DictionaryService extends BaseReactiveServiceImpl<Dictionary> {
* @return 结果
*/
public Mono<Dictionary> getByCode(String code) {
DictionaryRepository repository = this.getRepository();
return repository.findByCode(code);
}
/**
* 通过code同步查询
*
* @param code 编码
* @return 结果
*/
public Optional<Dictionary> get(String code) {
String cacheKey = DICT_KEY + code;
if (redisOperations.hasKey(cacheKey)) {
return Optional.of(redisOperations.get(cacheKey)).map(obj -> (Dictionary) obj);
} else {
Dictionary dictionary = mongoOperations.findOne(Query.query(Criteria.where("code").is(code)).limit(1),
Dictionary.class);
if (null != dictionary) {
redisOperations.set(cacheKey, dictionary);
return Optional.of(dictionary);
} else {
return Optional.empty();
}
}
return reactiveRedisOperations.hasKey(cacheKey)
.flatMap(hasKey -> {
if (hasKey) {
return reactiveRedisOperations.get(cacheKey).map(obj -> (Dictionary) obj);
}
DictionaryRepository repository = this.getRepository();
return repository.findByCode(code);
});
}
}

View File

@ -12,7 +12,8 @@ import lombok.Getter;
@AllArgsConstructor
public enum RestBeanCandidate implements NamedEnum {
REPOSITORY("Repository"), SERVICE("Service"), CONTROLLER("Controller"), VIEW_CONTROLLER("ViewController");
REPOSITORY("Repository"), SERVICE("Service"), CONTROLLER("Controller"),
VIEW_CONTROLLER("ViewController"), REACTIVE_VIEW_CONTROLLER("ReactiveViewController");
private final String name;
}

View File

@ -1,7 +1,9 @@
package com.flyfish.framework.beans.repository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.repository.DefaultRepository;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@ -12,11 +14,14 @@ import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension;
import org.springframework.data.mongodb.repository.config.ReactiveMongoRepositoryConfigurationExtension;
import org.springframework.data.repository.config.*;
/**
* 自定义的仓库注册器
*
* @author wangyu
*/
public class CustomRepositoryRegistrar {
@ -25,35 +30,59 @@ public class CustomRepositoryRegistrar {
private final RepositoryConfigurationExtension extension = new MongoRepositoryConfigurationExtension();
private final RepositoryConfigurationSource configurationSource;
private final CustomRepositoryBuilder builder;
// 异步的extension
private final RepositoryConfigurationExtension reactiveExtension = new ReactiveMongoRepositoryConfigurationExtension();
private final RepositoryConfigurationSource reactiveConfigurationSource;
private final CustomRepositoryBuilder reactiveBuilder;
public CustomRepositoryRegistrar(AnnotationMetadata metadata, ResourceLoader resourceLoader, Environment environment,
BeanDefinitionRegistry registry, BeanNameGenerator generator) {
// repo生成的构建器
this.configurationSource = new AnnotationRepositoryConfigurationSource(metadata,
EnableMongoRepositories.class, resourceLoader, environment, registry, generator);
// 异步的repo生成的构建器
this.reactiveConfigurationSource = new AnnotationRepositoryConfigurationSource(metadata,
EnableReactiveMongoRepositories.class, resourceLoader, environment, registry, generator);
// 构建器
this.builder = new CustomRepositoryBuilder(registry, extension,
configurationSource, resourceLoader, environment);
// 异步的构造器
this.reactiveBuilder = new CustomRepositoryBuilder(registry, reactiveExtension, reactiveConfigurationSource,
resourceLoader, environment);
}
/**
* 根据class直接注册bean
*
* @param clazz 编译后的class
*/
public void register(Class<?> clazz) {
if (ClassUtils.isAssignable(clazz, DefaultRepository.class)) {
register(clazz, configurationSource, extension, builder);
} else if (ClassUtils.isAssignable(clazz, DefaultReactiveRepository.class)) {
register(clazz, reactiveConfigurationSource, reactiveExtension, reactiveBuilder);
}
}
/**
* 注册仓库内部方法区分异步和同步
*
* @param clazz 类型
* @param configurationSource 配置源
* @param extension 扩展
* @param builder 构建器
*/
private void register(Class<?> clazz, RepositoryConfigurationSource configurationSource, RepositoryConfigurationExtension extension, CustomRepositoryBuilder builder) {
//生成BeanDefinition并注册到容器中
BeanDefinition origin = BeanDefinitionBuilder.genericBeanDefinition(clazz).getRawBeanDefinition();
//设置当前bean定义对象是单例的
origin.setScope("singleton");
// 构造配置
RepositoryConfiguration<? extends RepositoryConfigurationSource> configuration =
new DefaultRepositoryConfiguration<>(configurationSource, origin, extension);
BeanDefinitionBuilder definitionBuilder = builder.build(configuration);
extension.postProcess(definitionBuilder, configurationSource);
extension.postProcess(definitionBuilder, (AnnotationRepositoryConfigurationSource) configurationSource);
AbstractBeanDefinition beanDefinition = definitionBuilder.getBeanDefinition();
beanDefinition.setPrimary(configuration.isPrimary());
String beanName = StringUtils.uncapitalize(clazz.getSimpleName());
@ -61,6 +90,7 @@ public class CustomRepositoryRegistrar {
builder.getRegistry().registerBeanDefinition(beanName, beanDefinition);
}
public RepositoryConfigurationExtension getExtension() {
return extension;
}

View File

@ -9,6 +9,8 @@ import com.flyfish.framework.compiler.DynamicJavaCompiler;
import com.flyfish.framework.compiler.support.JavaSource;
import com.flyfish.framework.compiler.template.TemplateCompiler;
import com.flyfish.framework.domain.base.Vo;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.utils.Assert;
import com.flyfish.framework.utils.StringFormats;
import lombok.extern.slf4j.Slf4j;
@ -103,7 +105,7 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
// 分别生成实现类从repo到controller
templates.forEach((type, template) -> {
// 当且仅当存在vo时才编译view-controller
if (type == RestBeanCandidate.VIEW_CONTROLLER && !hasVo) {
if (testNotSupport(clazz, type, hasVo)) {
return;
}
source.setSuperClass(superClasses.getOrDefault(type, noOp).apply(restBean).getCanonicalName());
@ -128,6 +130,8 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
.forEach(clazz -> registerBean(clazz, registry));
loadedClasses.getOrDefault(VIEW_CONTROLLER, Collections.emptyList())
.forEach(clazz -> registerBean(clazz, registry));
loadedClasses.getOrDefault(REACTIVE_VIEW_CONTROLLER, Collections.emptyList())
.forEach(clazz -> registerBean(clazz, registry));
log.info("结束注册rest bean...");
}
@ -137,7 +141,7 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
* @param clazz class要注册的class
* @param registry 注册器注册bean用
*/
private void registerBean(Class<?> clazz, BeanDefinitionRegistry registry) {
private void registerBean(Class<?> clazz, BeanDefinitionRegistry registry) {
//生成BeanDefinition并注册到容器中
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
BeanDefinition beanDefinition = builder.getRawBeanDefinition();
@ -191,4 +195,23 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* 测试是否支持vo
*
* @param clazz
* @param type 注入类型
* @param hasVo 是否有vo
* @return 结果
*/
private boolean testNotSupport(Class<?> clazz, RestBeanCandidate type, boolean hasVo) {
switch (type) {
case VIEW_CONTROLLER:
return !hasVo || !DefaultRepository.class.isAssignableFrom(clazz);
case REACTIVE_VIEW_CONTROLLER:
return !hasVo || !DefaultReactiveRepository.class.isAssignableFrom(clazz);
default:
return false;
}
}
}

View File

@ -0,0 +1,38 @@
package #{packageName};
import #{beanClass};
import #{queryBeanClass};
import #{listViewClass};
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import com.flyfish.framework.bean.Result;
import com.flyfish.framework.configuration.annotations.PagedQuery;
import com.flyfish.framework.domain.base.Vo;
import com.flyfish.framework.service.BaseReactiveService;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("#{uri}")
public class #{className} {
@Autowired
protected BaseReactiveService<#{beanClassName}> service;
@GetMapping("views")
public Mono<Result<List<Vo<#{beanClassName}>>>> getVoList(@PagedQuery #{queryBeanClassName}#{queryBeanSuffix} qo) {
if (null != qo.getPageable()) {
return service.getPageList(qo)
.map(Result::accept)
.flatMap(result -> result.flatMap(list -> Flux.fromIterable(list)
.flatMap(item -> #{listViewClassName}().retrieve(item))
.collectList()));
}
return service.getList(qo).flatMap(item -> new #{listViewClassName}().retrieve(item))
.collectList()
.map(Result::accept);
}
}

View File

@ -8,28 +8,26 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
import com.flyfish.framework.bean.Result;
import com.flyfish.framework.configuration.annotations.PagedQuery;
import com.flyfish.framework.domain.base.Vo;
import com.flyfish.framework.service.BaseReactiveService;
import reactor.core.publisher.Mono;
import com.flyfish.framework.service.BaseService;
@RestController
@RequestMapping("#{uri}")
public class #{className} {
@Autowired
protected BaseReactiveService<#{beanClassName}> service;
protected BaseService<#{beanClassName}> service;
@GetMapping("views")
public Mono<Result<List<Vo<#{beanClassName}>>>> getVoList(@PagedQuery #{queryBeanClassName}#{queryBeanSuffix} qo) {
public Result<List<Vo<#{beanClassName}>>> getVoList(@PagedQuery #{queryBeanClassName}#{queryBeanSuffix} qo) {
if (null != qo.getPageable()) {
return service.getPageList(qo).map(page -> page.map(item -> new #{listViewClassName}().from(item)))
.map(Result::accept);
return Result.accept(service.getPageList(qo).map(item -> new #{listViewClassName}().from(item)));
}
return service.getList(qo).map(item -> new #{listViewClassName}().from(item))
.collectList()
.map(Result::accept);
return Result.accept(service.getList(qo).stream()
.map(item -> new #{listViewClassName}().from(item)).collect(Collectors.toList()));
}
}