最基础的
:controller,service,util,model
常见的
:exception,handler,constant,listener,
config
陌生的
:holder,DataSource.marker,cache,comparator.attribute,
config解释:
@Configuration定义配置类,跟xml文件里的<Beans>做映射,@bean=<Bean>,存在bean不生效的情况'使用了默认的装配'使用@Primary解决
@mapperscan注解:一般做do和tem绑定,在整个类里,需要注意的就是datasource。
DataSource.marker
:
实际上就是一些接口,用于做标记,作用跟自定义注解类似,但使用更为方便,不过需要在使用到的地方支持对接口做校验
比如
多数据源配置
:MasterDataSourceMarker,依托于mapperscan的值’markerInterface’,然后连接信息上使用@ConfigurationProperties,映射到对应的xml文件,这样就实现了主从数据源的连接配置。
@MapperScan(markerInterface = MasterDataSourceMarker.class,basePackages =
{"com.alphaliongroup.account.common.model"},sqlSessionTemplateRef = "masterSqlSessionTemplate")
和
public interface AccountTypeDetailAttributeDOMapper extends MasterDataSourceMarker {
cache
:
代码书写的原则就是尽可能复用,像cache,在多个地方都会用到,抽出来集中在一起,思路更加清晰。在很多项目里,代码都是在一直做重复,缺点显而易见:代码冗余繁杂,影响后续的业务。
holder:
这个命名让我有点奇怪,但它的本质不复杂,就是在干@autowired的活,像这种方式,实际上就是因为在项目没有启动时(一般是测试),spring不能为bean注入,所以选择手动的方式来做注入。当然@SpringBootTest实际上也是有一样的功能(
这里暂时存疑,因为没有实践过
)。
public class ApplicationContextHolder {
private static volatile ApplicationContext context = null;
public static final ApplicationContext getContext(){
return context;
}
public static final <T> T getBean(Class<T> clazz){
return context.getBean(clazz);
}
public static void setApplicationContext(ApplicationContext applicationContext) {
context = applicationContext;
}
}
exception和handler
exception没什么可说的,就是自定义异常,一般也只会有message作为异常处理的方法参数。handler则是对应的统一异常返回,需要注意的是返回给前端页面的一般是json格式的数据,需要特别注意。
/**
* @author vic 定义全局异常处理
* @RestControllerAdvice 是@controlleradvice 与@ResponseBody 的组合注解
*/
@RestControllerAdvice
@Slf4j
public class GlobalControllerExceptionHandler {
public static final String NOT_NULL_NOTICE = "should not be null";
@ExceptionHandler(value = {BindException.class})
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
public Result bindException(BindException ex) {
log.error("", ex);
return Result.fail(ex.getFieldError().getField() + ": " + ex.getFieldError().getRejectedValue()+","+ex.getFieldError().getDefaultMessage());
}
comparator.attribute:
这个让我比较困惑:它的功能是做两个字符串或日期的比较,但嵌套的层级比较多。
1.AttributeConditionOperationEnum:这个枚举类决定了比较的方向(小于大于相似)
2.AttributeTypeEnum:将多种类别的比较做成枚举类,DATE("date",new DateAttributeConditionMatcher())
3.AttributeConditionMatcher:接口
4.DateAttributeConditionMatcher,TextAttributeConditionMatcher:实现
使用:
AttributeTypeEnum attributeTypeEnum = AttributeTypeEnum.TEXT;
if(attributeMap.get(entry.getKey()) != null) {
flag = flag && attributeTypeEnum.getMatcher().match(entry.getValue(),
String.valueOf(attributeMap.get(entry.getKey())), enumMapMap.getKey());
listener:
简单介绍一下通过自定义注解来控制监听的接口
自定义注解监听可以对请求做监听,kafka topic的监听可以使用直接监听
通过自定义注解@permission,以及value(这里还写了一个常量类来控制)
ApplicationListener<ContextRefreshedEvent> :核心接口,实现该接口,补全onApplicationEvent方法,
我们自定义的监听处理器生效,同时所有的监听上的逻辑处理也在这里完成。
@Permission(Permissions.Account)
public class AccountController {
每个接口都绑定了对应的permission,获取到注解,再做对应解析,就能做监听
步骤
WorkflowEventDispatcher.addListener(type, workflowListener);
将所写的监听加入,怎么确定监听范围(接口数量?)