2021.7.6springboot标准化项目
1,mavne仓库
<mirror>
<id>total</id>
<mirrorOf>*</mirrorOf>
<name>Hengtian</name>
<url>http://nexus.hengtiansoft.com/content/groups/total/</url>
</mirror>
2,四个模块
- common:公共模块
- job:定时任务模块(示例)(可选)
- security-support:spring security 支持模块 (可选)
- user-service:服务示例
前三个都是基础模块
1,common
-
config
- ExceptionHandlerConfig:异常处理器配置
- jsonConfig:json配置,设置了全局的序列化和反序列化
- ProfileConfig:这个配置类是用来获取当前使用环境,该功能主要是用来在记录日志的时候,根据不同的环境来记录日志。
- redisConfig:根据@ConditionalOnClass注解来判断是否加载此配置类,此配置类注释提供了 RedisCacheManager 对使用 redis 做缓存的时候,各个 cache-key 过期时间的设置,以及操作 redis 的工具类 redisOperation
- validatorCofig:快速验证,即发现一个不正确就返回。
-
constant:常量
- authenticationConstants:认证相关的常量
- authorizationConstants:授权相关的常量
- pageConstants:分页信息相关的常量
- responseCode:响应码相关的常量
- responseConstants:响应信息相关的常量
- responseMsg:相应提示信息相关的常量
-
entity:实体
- dto:数据传输对象
- pageParams:分页参数类
- pageination:分页结果描述类
- userDetailsDto:
- userPrincipalDto:封装了用户的一些信息
- exception:异常
- businessException:继承runtimeException,业务异常类
- jsonException:继承runtimeException,json工具异常类
- validationException:继承runtimeException,参数校验的异常类
- vo:视图对象,用于展示层
- pageVo:分页结果
- responseBody:业务结果返回类
- response:业务相应vo
- dto:数据传输对象
-
factory:工厂类
- responseFactory:业务相应类
-
format:统一格式类
- jacksonCustomDateFormat:json日期格式类
-
handler:处理器
- globalErrorController:全局错误控制
- globalExceptionHandler:全局异常捕获,包括认证异常,业务异常,json异常,校验异常,以及环境异常
-
security:安全
- cas:单点登录
- CasUserPrincipalDto:封装了用户的一些信息以及方法
- enums:枚举
- urlIterceptionStrategyEnums:基于URL鉴权时的访问策略
- jackson:
- casUserPrincipalDtoDeserializer:反序列化处理器
- casUserPrincipalDtoMixin:用于指定CasUserPrincipalDTO的序列化与反序列化
- SecurityJackson2ExtendedModule:支持Security相关的扩展自定义类型序列化与反序列化,在Spring Session持久化到Redis时使用
- UserAuthenticationTokenDeserializer:UserAuthenticationToken反序列化处理器
- UserAuthenticationTokenMixin:用于指定UserAuthenticationToken的序列化与反序列化
- UserAuthenticationToken:用于指定UserAuthenticationToken的序列化与反序列化
- property:属性
- CasProperties:cas登录配置
- SecurityURIProperties:url 授权相关配置
- token:令牌
- UserAuthenticationToken:token
- cas:单点登录
-
util:工具
- beanUtils:bean拷贝工具类
- jsonResponseUtils:json返回工具类
- jsonUtils:json工具类
- mapUtils:map工具类
- pageUtils:分页工具类
- redisUtils:redis工具类
- springContextUtils:spring应用上下文工具类
- streamUtils:集合流操作工具类,使用并行流,需要保证函数式是无状态、线程安全的
- uuidUtils:uuid生成工具类
- validationUtils:数校验工具类,如果违反判断条件,则抛出ValidationException异常
-
valid:有效的
- validGroups:增删改查验证分组
配置文件
-
resource
-
META-INF
- spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration
这个就是注解
@EnableAotoConfiguration
的全类名关于
@EnableAutoConfiguration
大家估计都不陌生,@springbootApplication
下的三大注解之一,@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class<?>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {}; }
然后在
@EnableAutoConfiguration
类中,最重要的是@Import(AutoConfigurationImportSelector.class)
,借助
AutoConfigurationImportSelector
,@EnableAutoConfiguration
可以帮助springboot 应用将所有符合条件的@Configuration
配置都加载到当前springboot 创建并使用的IOC容器。同时,借助于spring框架原有的一个工具类:springFactoriesLoader的支持,@EnableAutoConfiguration 可以智能的自动配置功效才得以大工告成。
在 AutoConfigurationImportSelector 类中可以看到 通过
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
SpringFactoriesLoader.loadFactoryNames()把spring-boot-autoconfigure.jar /MATE-INF/spring.factories 中每一个 xxxAutoConfiguration 文件都加载到容器中,spring.factories 文件里每一个 xxxAutoConfiguration 文件一般都会有下面的条件注解:
- @ConditionalOnClass : classpath中存在该类时起效
- @ConditionalOnMissingClass : classpath中不存在该类时起效
- @ConditionalOnBean : DI容器中存在该类型Bean时起效
- @ConditionalOnMissingBean : DI容器中不存在该类型Bean时起效
- @ConditionalOnSingleCandidate : DI容器中该类型Bean只有一个或@Primary的只有一个时起效
- @ConditionalOnExpression : SpEL表达式结果为true时
- @ConditionalOnProperty : 参数设置或者值一致时起效
- @ConditionalOnResource : 指定的文件存在时起效
- @ConditionalOnJndi : 指定的JNDI存在时起效
- @ConditionalOnJava : 指定的Java版本存在时起效
- @ConditionalOnWebApplication : Web应用环境下起效
- @ConditionalOnNotWebApplication : 非Web应用环境下起效
... org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
SpringFactoriesLoader
SpringFactoriesLoader 属于 spring 框架私有的一种扩展方案(类似java的spi方案 java.util.ServiceLoader),其主要功能就是从指定的配置文件MATE-INF/spring-factories 加载配置,spring-factories 时一个典型的java properties 文件。只不过 key 和 value都是 java 类型的完整类名,比如:
org.springframework.boot.autoconfigure.EnableAutoConfiguration
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
对于 @EnableAutoConfiguration 来说,SpringFactoriesLoader 的用途稍微不同一些,其本意是为了提供 spi 扩展的场景,而在 @EnableAutoConfiguration 场景中,它更多提供了一种配置查找的功能支持,即根据 @EnableAutoConfiguration 的完整类名 org.springframework.boot.autoconfigure.EnableAutoConfiguration
作为查找的key ,获得对应的一组 @Configuration 类。
SpringFactoriesLoader :是一个抽象类,类中定义的静态属性定义了其加载资源的路径:
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"
;此外还有三个静态方法:- loadFactories:加载指定的factoryClass并进行实例化
- loadFactoryNames:加载指定的factoryClass的名称集合
- instantiateFactory:对指定的factoryClass进行实例化。
在loadFactories 方法中调用了 loadFactoryNames 以及 instantiateFactory 方法
public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) { Assert.notNull(factoryType, "'factoryType' must not be null"); ClassLoader classLoaderToUse = classLoader; if (classLoader == null) { classLoaderToUse = SpringFactoriesLoader.class.getClassLoader(); } List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse); if (logger.isTraceEnabled()) { logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames); } List<T> result = new ArrayList(factoryImplementationNames.size()); Iterator var5 = factoryImplementationNames.iterator(); while(var5.hasNext()) { String factoryImplementationName = (String)var5.next(); result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse)); } AnnotationAwareOrderComparator.sort(result); return result; }
loadFactories 方法首先获取类加载器,然后调用 loadFactoryNames 方法获取所有指定资源的名称集合 ,接着调用 instantiateFactory 方法实例化这些资源类并将其添加到result集合中,最后调用
AnnotationAwareOrderComparator.sort(result);
方法进行集合的排序。 -
2,job
-
config
- scheduleConfig:设置定时任务线程池大笑
-
task:定时任务
- scheduledTask:定时任务,单任务同步,多任务并行
关于定时任务,我好像用过 quartz ,xxl-job倒是没有过,朋友说他现在的项目框架的定时任务是 xxl-job
- xxl-job :是分布式任务调度平台
- quartz:任务调度,定时任务框架
**总体:**应该是各有优劣
3,security support
看的我是云里雾里的。大致功能可能就是 登录拦截校验,登录授权,校验的话分为前端校验和后端校验两部分吧,以及访问认证,再就是 防御csrf 攻击,在细的就是:授权的时候 密码加密加盐,或者用户的一些信息加密,解密。
4,user-service
http://localhost:8080/swagger-ui.html#/,swagger
就是正常的实现业务逻辑。
dao层继承Mapper,然后结合自定义查询。
5,关于技术选型
95,dto,vo,po
vo(view object):视图对象,用于展示层,就是前端页面展示的字段
dto(data transfer object):数据传输对象,用于视图层和服务层之间的转换,就是vo与po之间的中间层
po(persistent object):持久层,每个对象都与数据库对应
96,spring cache(缓存)
@EnableCaching
使用上面的注解在springboot主启动类中开启spring cache,大致作用就是,(要补充的就是 spring cache 还有其他几个注解 用在作用在方法上,和作用在类上)当缓存的注解作用在方法上,就是实现当我们调用这个方法时,首先回去缓存中查找是否有这个方法,如果有就直接调用,没有就调用方法本身,并且将执行的结果返回在缓存中。(需要注意的是,它们是使用 (key:value)的方式存的,每个开启缓存的方法都有一个 key,然后他们的执行结果 就是value)
97,java的spi方案
spi 全称:service provider interface,jdk内置的一种服务发现机制。
简单的来说就是服务发现机制,机制:就是提供实现类的发现机制,通过spi模式能够将接口和实现类灵活配置,调用方无需关心具体实现类是什么,只需要面向接口编程。
具体使用:
在写完接口和实现类后,在项目的 resources 下创建 MATE-INF/services/接口的全限定名,然后文件里的内容就是,该接口对应的具体实现类的全限定名
具体能干啥:
目前没发现,有人说dubbo 就是这种机制,以及 java.sql.Driver 的spi实现(各大数据库厂商的驱动)
说是将装配的控制权移交程序之外,类似 ioc
98,package-info.java
叫做包服务类,通过javadoc生成api文档
1. 大致来说就是可以在其中定义包中共用的属性和方法,且这些属性和方法无需import,可以在其他类中直接使用
2. 一般可以作为包功能说明信息的载体,典型的适用于按功能模块分包开发的web应用。
三个作用:
- 为标注在包上 Annotation 提供便利
- 声明友好类和常亮包
- 提供包的整体注解说明
99,get it
1,package-info.java
2,java的spi方案
3,@EnableCaching:开启spring cache(缓存)
4,dto,vo,po