文章目录
1 配置数据总出错? 搞清楚加载顺序吧
1.1 yml文件放在resource的根目录下:
[
测试:
1.2多环境配置
如果更改环境,需要重新打包,
需要一种:不修改文件,就可以随意切换环境,如下:
第一步:
第二步:
第三步:
打包:会在target中生成jar包
cd target
2定时任务不定时啦?
例子:
第一步: 编写代码
第二步:在启动类上加注解@EnableScheduling
启动发现: 只有task01 执行啦,task02 并没有执行
因为:task01 一直死循环,直占用线程,导致没有多余的线程去执行task02 任务啦
解决:
方式一:
方式2:
第一步:添加配置类
@Configuration
public class ScheduleConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(5);
return taskScheduler;
}
}
3 异步任务你有没有处理好?
第一步:
package com.imooc.spring.escape.async_task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
@Slf4j
@Service
public class AsyncService {
@Async
public void asyncProcess01() throws Exception {
log.info("AsyncService: Start To Process 01 -> {}",
Thread.currentThread().getName());
Thread.sleep(2000);
log.info("AsyncService: Done To Process 01 -> {}",
Thread.currentThread().getName());
}
@Async
public Future<String> asyncProcess02() throws Exception {
log.info("AsyncService: Start To Process 02 -> {}",
Thread.currentThread().getName());
Thread.sleep(2000);
log.info("AsyncService: Done To Process 02 -> {}",
Thread.currentThread().getName());
return new AsyncResult<>("ImoocQinyi");
}
@Async
public void asyncProcess03() throws Exception {
log.info("AsyncService: Start To Process 03 -> {}",
Thread.currentThread().getName());
Thread.sleep(2000);
throw new RuntimeException("throw exception in asyncProcess03.");
}
}
第二步: 在启动类中加注解@EnableAsync
第三步: 编写测试类:
3.1 异步任务的线程池怎么配置的?异步有返回结果, 但是有异常,一直停在哪里怎么办?
方式一:
方式二:
package com.imooc.spring.escape.async_task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Configuration
public class AsyncTaskConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("imooc-qinyi-task-");
executor.setCorePoolSize(2);
executor.setMaxPoolSize(8);
executor.setKeepAliveSeconds(5);
executor.setQueueCapacity(100);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
//异步有返回结果, 但是有异常,一直停在哪里怎么办?
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable ex, Method method,
Object... params) {
// 发送报警邮件, 短信等等
log.error("Async Task Has Some Error: {}, {}, {}",
ex.getMessage(),
method.getDeclaringClass().getName() + "." + method.getName(),
Arrays.toString(params));
}
};
}
}
4jackson
4.1 ObjectMapperConfig
package com.imooc.spring.escape.use_jackson;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class ObjectMapperConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 忽略 json 字符串中不识别的字段
mapper.configure(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false
);
return mapper;
}
}
4.2 常用注解
4.2.1使用
第一步:
@Getter
@AllArgsConstructor
public enum CouponStatus {
USABLE("可用的", 1),
USED("使用过的", 2);
private String desc;
private Integer code;
}
第二步:
package com.imooc.spring.escape.use_jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) 排除值为null的值参与序列化
@JsonIgnoreProperties({"couponCode", "status"})不参与序列化的注解,
public class Coupon {
@JsonIgnore 忽略
private int id;
@JsonProperty("user") 换序列化的名称
private Long userId;
private String couponCode;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "hh:mm:ss")
private Date assignTime;
private CouponStatus status;
private CouponTemplate template;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class CouponTemplate {
private String name;
private String logo;
}
public static Coupon fake() {
return new Coupon(
1, 100L, "123456", new Date(), CouponStatus.USABLE,
new CouponTemplate("CouponTemplate", "imooc")
);
}
}
测试:
package com.imooc.spring.escape.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.spring.escape.use_jackson.Coupon;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.text.SimpleDateFormat;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestObjectMapper {
@Autowired
private ObjectMapper mapper;
@Test
public void testUseJacksonAnnotation() throws Exception {
Coupon coupon = Coupon.fake();
coupon.setTemplate(null);
log.info("ObjectMapper Se Coupon: {}",
mapper.writeValueAsString(coupon));
}
}
返回结果: {“user”:100,“assignTime”:“04:38:57”}
4.2.2JsonSerializer
第一步:
package com.imooc.spring.escape.use_jackson;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.SimpleDateFormat;
public class CouponSerialize extends JsonSerializer<Coupon> {
@Override
public void serialize(Coupon coupon, JsonGenerator generator,
SerializerProvider serializers) throws IOException {
// 开始序列化
generator.writeStartObject();
generator.writeStringField("id", String.valueOf(coupon.getId()));
generator.writeStringField("userId", coupon.getUserId().toString());
generator.writeStringField("couponCode", coupon.getCouponCode());
generator.writeStringField("assignTime",
new SimpleDateFormat("HH:mm:ss").format(coupon.getAssignTime()));
generator.writeStringField("status", coupon.getStatus().getDesc());
generator.writeStringField("name", coupon.getTemplate().getName());
generator.writeStringField("logo", coupon.getTemplate().getLogo());
// 结束序列化
generator.writeEndObject();
}
}
第二步:
package com.imooc.spring.escape.use_jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
//@JsonInclude(JsonInclude.Include.NON_NULL)
//@JsonIgnoreProperties({"couponCode", "status"})
@JsonSerialize(using = CouponSerialize.class)
public class Coupon {
// @JsonIgnore
private int id;
// @JsonProperty("user")
private Long userId;
private String couponCode;
// @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "hh:mm:ss")
private Date assignTime;
private CouponStatus status;
private CouponTemplate template;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class CouponTemplate {
private String name;
private String logo;
}
public static Coupon fake() {
return new Coupon(
1, 100L, "123456", new Date(), CouponStatus.USABLE,
new CouponTemplate("CouponTemplate", "imooc")
);
}
}
测试:
@Test
public void testUseJacksonAnnotation() throws Exception {
Coupon coupon = Coupon.fake();
coupon.setTemplate(null);
log.info("ObjectMapper Se Coupon: {}",
mapper.writeValueAsString(coupon));
}
返回结果:
{“id”:“1”,“userId”:“100”,“couponCode”:“123456”,“assignTime”:“00:48:35”,“status”:“可用的”, “name”:“CouponTemplate”,“logo”:“imooc”}
4.2.3 反序列化
@Test
public void testUseJacksonAnnotation() throws Exception {
String jsonCoupon = "{\"id\":\"1\",\"userId\":\"100\",\"couponCode\":\"123456\"," +
"\"assignTime\":\"00:48:35\"," +
"\"status\":\"USABLE\"}";
mapper.setDateFormat(new SimpleDateFormat("HH:mm:ss"));
log.info("{}", mapper.readValue(jsonCoupon, Coupon.class).getId());
}