@Conditional 满足条件给容器注册Bean(在配置类 @Configuration 的类和方法上配置)

需要实现Condition接口, 实现matches方法

public class LdCondition implements Condition{
@Override
public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
//从这里获取配置文件中 active 的值,根据当前的 active 值决定是否加载类
String[] activeProfiles = environment.getActiveProfiles();
for (String active : activeProfiles) {
if(active.equals(ActiveEnum.open_active.getActive().toString())){
return true;
}
}
return false;
}
} 标注在类上:
一个类中可以注入很多实例,@Conditional标注在类上就决定了一批bean是否注入。 标记在方法上 @Configuration
public class BeanConfig {
//只有一个类时,大括号可以省略
//如果LdCondition的实现方法返回true,则注入这个bean
@Conditional({LdCondition.class})
@Bean("person")
public Person person(){
return new Person("ld",22);
}
} @ConditionalOnMissingBean:
容器中没有就注入,有就不注入。 @ConditionalOnMissingBean:
容器中没有就不注入,有就注入。

FilterRegistrationBean 自定义过滤器(配置类 @Configuration 中)

使用FilterRegistrationBean来注册Filter:

    @Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
FilterRegistrationBean<CorsFilter> corsFilter = new FilterRegistrationBean<>();
//设置优先级
corsFilter.setOrder(Ordered.HIGHEST_PRECEDENCE + 10);
//注册过滤器
corsFilter.setFilter(new CorsFilter());
//拦截路径
corsFilter.addUrlPatterns("/api/*");
return corsFilter;
}

SpringBoot 整合 Swagger2(配置类 @Configuration 上)

依赖:
implementation "io.springfox:springfox-swagger2:$swaggerVersion"
implementation "io.springfox:springfox-swagger-ui:$swaggerVersion" 一般 swagger 需要的权限(需要在对应的模块进行排除):
http://localhost:8080/swagger-resources/configuration/ui
http://localhost:8080/swagger-resources
http://localhost:8080/api-docs
http://localhost:8080/swagger-ui.html
http://localhost:8080/swagger-resources/configuration/security
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/"); @Api("评论接口"):
用在类上,说明该类的作用 @ApiOperation(value="获取评论", notes="根据id获取评论"):
用在方法上,说明方法的作用,标注在具体请求上。
value和notes的作用差不多,都是对请求进行说明;
tags则是对请求进行分类的,
比如你有好几个controller,分别属于不同的功能模块,那这里我们就可以使用tags来区分了。 @ApiImplicitParams:
用在方法上包含一组参数说明。 @ApiImplicitParam(name = "id", value = "12", required = true, dataType = "String"):
用在@ApiImplicitParams注解中,指定一个请求参数的各个方面。 @ApiResponses:
用于表示一组响应 @ApiResponse:
用在@ApiResponses中,一般用于表达一个错误的响应信息。 @ApiModel:
描述一个Model的信息
这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述时。
表明这是一个被swagger框架管理的model,用于class上。 @ApiModelProperty:
描述一个model的属性,就是标注在被标注了@ApiModel的class的属性上,
这里的value是对字段的描述,example是取值例子。 Swagger2配置: @EnableSwagger2
@Configuration
public class SwaggerConfiguration { @Bean
public Docket haloDefaultApi() { return buildApiDocket("content",
"api.content",
"/api/content/**");
} @Bean
public Docket haloAdminApi() { return buildApiDocket("admin",
"api.admin",
"/api/admin/**");
} private Docket buildApiDocket(@NonNull String groupName, @NonNull String basePackage, @NonNull String antPattern) {
Assert.hasText(groupName, "Group name must not be blank");
Assert.hasText(basePackage, "Base package must not be blank");
Assert.hasText(antPattern, "Ant pattern must not be blank"); return new Docket(DocumentationType.SWAGGER_2)
.groupName(groupName)
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.ant(antPattern))
.build()
.apiInfo(apiInfo());
} private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API Documentation")
.description("Documentation for API")
.version("1.0")
.build();
}
} 启动后访问:
http://localhost:8080/swagger-ui.html

@EnableWebMvc 用于导入 Spring Web MVC configuration(配置类 @Configuration 上)

将此注释添加到 @Configuration 类将导入来自 WebMvcConfigurationSupport 的 Spring MVC配置。

@EnableWebMvc == @Import({DelegatingWebMvcConfiguration.class})

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "controller")
@PropertySource(value = "classpath:application.yaml", ignoreResourceNotFound = true, encoding = "UTF-8")
public class WebMvcAutoConfiguration implements WebMvcConfigurer { //文件协议
private static final String FILE_PROTOCOL = "file:///"; //配置信息实体
private final HaloProperties haloProperties; //自动注入HaloProperties
public WebMvcAutoConfiguration(HaloProperties haloProperties) {
this.haloProperties = haloProperties;
} /**
* Spring Boot底层通过HttpMessageConverters(依靠Jackson库)将Java实体类输出为JSON格式。
*
* MappingJackson2HttpMessageConverter可以将Java对象转换为application/json。
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.stream()
.filter(c -> c instanceof MappingJackson2HttpMessageConverter)
// ifPresent():如果存在一个值,则使用该值执行给定的操作,否则什么也做不成
.findFirst().ifPresent(converter ->
{
// MappingJackson2HttpMessageConverter:读写Json转换器
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = (MappingJackson2HttpMessageConverter) converter;
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
// JsonComponentModule 来扫描被 @JsonComponent 注解的类,
// 并自动注册 JsonSerializer 和 JsonDeserializer。
JsonComponentModule module = new JsonComponentModule();
// addSerializer():为序列化模块添加自定义序列化程序来处理特定类型的值。
// PageJacksonSerializer:Page对象的序列化
module.addSerializer(PageImpl.class, new PageJacksonSerializer());
// builder.modules():指定序列化模块
ObjectMapper objectMapper = builder.modules(module).build();
// 设置自定义 objectMapper,未设置则使用默认 objectMapper
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
});
} /**
* 自定义参数处理器
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new AuthenticationArgumentResolver());
} /**
* 配置静态资源路径
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String workDir = FILE_PROTOCOL + haloProperties.getWorkDir();
//映射 /** 的请求到 addResourceLocations() 指定的目录
registry.addResourceHandler("/**")
.addResourceLocations(workDir + "templates/themes/")
} /**
* 添加转换器(Converter)和格式器(Formatters)
*/
@Override
public void addFormatters(FormatterRegistry registry) {
//ConverterFactory:range范围转换器的工厂(可以将对象从S转换为R的子类型)
registry.addConverterFactory(new StringToEnumConverterFactory());
} /**
* 配置 freemarker
*/
@Bean
public FreeMarkerConfigurer freemarkerConfig(HaloProperties haloProperties) throws IOException, TemplateException {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
//设置模板路径与字符集
configurer.setTemplateLoaderPaths(FILE_PROTOCOL + haloProperties.getWorkDir() + "templates/", "classpath:/templates/");
configurer.setDefaultEncoding("UTF-8"); Properties properties = new Properties();
properties.setProperty("auto_import", "/common/macro/common_macro.ftl as common,/common/macro/global_macro.ftl as global"); configurer.setFreemarkerSettings(properties); return configurer;
} /**
* 配置视图解析器来转换基于字符串的视图名称
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
resolver.setCache(false);
resolver.setSuffix(HaloConst.SUFFIX_FTL);
resolver.setContentType("text/html; charset=UTF-8");
registry.viewResolver(resolver);
}
}

@PropertySource 加载指定的配置文件到 Spring 的 Environment 中(配置类 @Configuration 上)

@PropertySource(value = "classpath:application.yaml",
ignoreResourceNotFound = true, encoding = "UTF-8") //true表示属性源是可选的 用于 PropertySource 在 Spring 的上 添加 Environment。与 @Configuration 类一起使用。 获取配置文件中的值通过 Environment 具体使用方法:
@Autowired
private Environment env; 或者 使用 @value 注解,从配置文件读取值:
@Value("${test.value}")

HandlerMethodArgumentResolver 自定义参数解析

自定义解析器需要实现 HandlerMethodArgumentResolver 接口。

实现自定义参数解析器步骤:1、自定义注解   2、自定义参数解析器   3、注册   4、在需要注入属性的 controller 添加注解

自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface UserToken {String value() default "user";} 自定义参数解析器:
@Component
public class AuthenticationArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 解析器是否支持当前参数
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 指定参数如果被应用 UserToken 注解,则使用该解析器。
// 如果直接返回true,则代表将此解析器用于所有参数
return parameter.hasParameterAnnotation(UserToken.class);
} @Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {}
} 注册:
public class WebMvcAutoConfiguration implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new AuthenticationArgumentResolver());
}
}

序列化和反序列化

层次低的一种是 Byte <---> Message,二进制与程序内部消息对象之间的转换,就是常见的序列化/反序列化。

另外一种是 Message <---> Message,程序内部对象之间的转换,比较高层次的序列化/反序列化。

Http序列化和反序列化(高层次)的核心是HttpMessageConverter。

@JsonSerialize @JsonDeserialize @JsonComponent

如果使用 Jackson 序列化和反序列化 JSON 数据,
您可能需要编写自己的 JsonSerializer 和 JsonDeserializer 类。
自定义序列化程序通常通过模块向 Jackson 注册,
但 Spring Boot 提供了另一种 @JsonComponent 注释,可以更容易地直接注册 Spring Beans。 您可以直接在 JsonSerializer 或 JsonDeserializer 实现上使用 @JsonComponent 注释。
您还可以在包含 JsonSerializer 或 JsonDeserializer 作为内部类的类上使用它。 @JsonSerialize:
可以实现数据转换功能,此注解用于属性或者 getter() 方法上。 @JsonDeserialize:
此注解用于属性或者 setter() 方法上,用于在反序列化时可以嵌入我们自定义的代码。 @JsonComponent:
注释允许我们将带注释的类公开为Jackson序列化器和/或反序列化器,而无需手动将其添加到ObjectMapper。 @JsonSerialize(using = JsonDateSerialize.class)
@JsonDeserialize(using = JsonDateDeserialize.class)
private Date birthday;

最新文章

  1. Linux设备管理(三)_总线设备的挂接
  2. HTML5+JS 《五子飞》游戏实现(一)规则
  3. 初识WebSocket协议
  4. 谈谈.NET中常见的内存泄露问题——GC、委托事件和弱引用
  5. TCP/IP 教程
  6. Smallest Rectangle Enclosing Black Pixels 解答
  7. android-数据持久化
  8. dataset的使用和图片延时加载的实现
  9. 笔记:Maven 私服 Nexus 权限控制
  10. Day6_time模块
  11. 第九节:从源码的角度分析MVC中的一些特性及其用法
  12. MySQL安装与启动——Windows系统下
  13. 安卓开发学习之Menu
  14. AngularJs 指令中 的Scope属性
  15. react native中如何往服务器上传网络图片
  16. [笔记] Redis的安装与配置超级详细
  17. 20145329 《网络对抗技术》Web基础
  18. UVa 1220 Hali-Bula的晚会(树的最大独立集)
  19. perl6: hash小笔记
  20. 高级浏览器-SRWare Iron 29.0.1600.0 版本发布

热门文章

  1. Sublime Text 注册及使用相关
  2. BZOJ 4399: 魔法少女LJJ(线段树)
  3. 3 August
  4. Linux基本常用命令|ubuntu获取root权限
  5. (65)C# 任务
  6. UITableView 支持左右滑动(二)
  7. Java并发:搞定线程池(中)
  8. 洛谷P1219 八皇后
  9. QTP 保留对象
  10. 搭建邮件服务器 使用Postfix与Dovecot