通过 IDEA 创建。
通过 网站创建。
org.springframework.boot
spring-boot-starter-aop
使用 AOP 的思想进行日志记录
@Aspect
@Component
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(public * com.example.luckymoney.controller.*.*(..))")
public void log() {
}
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
logger.info("url={}", request.getRequestURL());
//method
logger.info("method={}", request.getMethod());
//ip
logger.info("ip={}", request.getRemoteAddr());
//类方法
logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
//参数
logger.info("args={}", joinPoint.getArgs());
}
@After("log()")
public void doAfter() {
logger.info("\n");
}
@AfterReturning(returning = "object", pointcut = "log()")
public void doAfterReturning(Object object) {
logger.info("response={}", object.toString());
}
}
logback 帮助文档
引入依赖
org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE
引入 logback-pring.xml 配置文件
logback
${CONSOLE_LOG_PATTERN}
UTF-8
%d-%msg%n
log_info.log
%d - %msg%n
UTF-8
logInfo.%d{yyyy-MM-dd}.log
30
10KB
ERROR
DENY
ACCEPT
log_error.log
ERROR
error
%d - %msg%n
UTF-8
logError.%d{yyyy-MM-dd}.log
30
10KB
异常处理的作用:
异常处理的操作:
import lombok.Data;
@Data
public class MyException extends RuntimeException {
private Integer code;
public MyException (Integer code,String message){
super(message);
this.code = code;
}
public MyException(ResultEnum resultEnum){
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
}
import com.example.luckymoney.domain.Result;
import com.example.luckymoney.exception.MyException;
import com.example.luckymoney.utils.ResultUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class ExceptionHandle {
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result handle(Exception e){
if(e instanceof MyException){
MyException myException = (MyException) e;
return ResultUtils.error(myException.getCode(),myException.getMessage());
}else{
logger.error("[系统异常]");
return ResultUtils.error(-1,"未知错误");
}
}
}
import com.example.demo01.pojo.JsonResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 抛出异常时会被这个类捕获
@ControllerAdvice
public class AllExceptionHandler {
public static final String ERROR_VIEW = "error";
@ExceptionHandler(value = Exception.class)
public Object errorHandler(HttpServletRequest reqest,
HttpServletResponse response, Exception e) throws Exception {
e.printStackTrace();
if (isAjax(reqest)) {
JsonResult jsonResult = JsonResult.errorException(e.getMessage());
return jsonResult;
} else {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", reqest.getRequestURL());
mav.setViewName(ERROR_VIEW);
return mav;
}
}
/**
* 判断是不是 Ajax 请求
* */
public static boolean isAjax(HttpServletRequest httpRequest){
return (httpRequest.getHeader("X-Requested-With") != null
&& "XMLHttpRequest"
.equals( httpRequest.getHeader("X-Requested-With").toString()) );
}
}
拦截器的作用:
拦截器的实现
import com.example.demo01.controller.interceptor.OneInterceptor;
import com.example.demo01.controller.interceptor.TwoInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
/**
* 拦截器按照顺序执行
*/
registry.addInterceptor(new OneInterceptor()).addPathPatterns("/one/**")
.addPathPatterns("/two/**");
registry.addInterceptor(new TwoInterceptor()).addPathPatterns("/two/**")
.addPathPatterns("/one/**");
super.addInterceptors(registry);
}
}
异步的作用:
异步的实现:
开启异步调用方法
@EnableAsync
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
@Component
public class AsyncTask {
@Async
public Future doTask11() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(1000);
long end = System.currentTimeMillis();
System.out.println("任务1耗时:" + (end - start) + "毫秒");
return new AsyncResult<>(true);
}
@Async
public Future doTask22() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(700);
long end = System.currentTimeMillis();
System.out.println("任务2耗时:" + (end - start) + "毫秒");
return new AsyncResult<>(true);
}
@Async
public Future doTask33() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(600);
long end = System.currentTimeMillis();
System.out.println("任务3耗时:" + (end - start) + "毫秒");
return new AsyncResult<>(true);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;
@RestController
@RequestMapping("tasks")
public class DoTask {
@Autowired
private AsyncTask asyncTask;
@RequestMapping("test1")
public String test1() throws Exception {
long start = System.currentTimeMillis();
Future a = asyncTask.doTask11();
Future b = asyncTask.doTask22();
Future c = asyncTask.doTask33();
while (!a.isDone() || !b.isDone() || !c.isDone()) {
if (a.isDone() && b.isDone() && c.isDone()) {
break;
}
}
long end = System.currentTimeMillis();
String times = "任务全部完成,总耗时:" + (end - start) + "毫秒";
System.out.println(times);
return times;
}
}
@EnableScheduling
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class TestTask {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
// @Scheduled(fixedRate = 3000)
@Scheduled(cron = "3-30 * * * * ? ")
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}
}
测试 dao:
import com.nick.hello.dao.UserMapper;
import com.nick.hello.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Iterator;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableAutoConfiguration
public class HellospringApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void selectAllTest() {
List list = userMapper.selectAll();
System.out.println(list);
Iterator iterator = list.iterator();
int i = 1;
while (iterator.hasNext()) {
User user = (User)iterator.next();
System.out.println(i + " : " + user.getId());
i++;
}
}
}
测试 service:
import com.example.luckymoney.domain.Luckymoney;
import com.example.luckymoney.service.LuckymoneyService;
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;
@RunWith(SpringRunner.class)
@SpringBootTest
public class LuckymoneyServiceTest {
@Autowired
private LuckymoneyService luckymoneyService;
@Test
public void findOneTest(){
Luckymoney luckymoney = luckymoneyService.findOne(1);
System.out.println(luckymoney);
}
}
测试 controller:
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
class LuckymoneyControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void list() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/luckymoneys"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string("abc")); //判断返回内容是否是 abc
}
}
SpringBoot 整合 freemarker:
# freemarker 静态资源配置
spring.freemarker.template-loader-path=classpath:/templates/
# 生产环境就改为 true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
org.springframework.boot
spring-boot-starter-freemarker
SpringBoot 整合 thymeleaf:
# thymeleaf 静态环境配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
#springboot 官方文档建议我们关闭thymeleaf的缓存
spring.thymeleaf.cache=false
org.springframework.boot
spring-boot-starter-thymeleaf
# MyBatis 配置
mybatis.type-aliases-package=com.example.demo01.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
mapper.mappers=com.example.demo01.utils.MyMapper
mapper.not-empty=false
mapper.identity=MYSQL
# druid 数据源配置
spring.datasource.url=jdbc:mysql://123.56.25.127:3306/db_leecx?characterEncoding=utf8&useSSL=false
spring.datasource.username=zq
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true
# pagehelper 配置
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
com.alibaba
druid
1.1.10
mysql
mysql-connector-java
5.1.41
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.1
tk.mybatis
mapper-spring-boot-starter
1.2.4
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.12
org.mybatis.generator
mybatis-generator-core
1.3.2
compile
true
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
public class GeneratorDisplay {
public void generator() throws Exception{
List warnings = new ArrayList();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
public static void main(String[] args) throws Exception {
try {
GeneratorDisplay generatorSqlmap = new GeneratorDisplay();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://123.56.25.127:3306/db_luckymoney?characterEncoding=utf-8
username: zq
password: admin
jpa:
hibernate:
ddl-auto: update
show-sql: true
org.springframework.boot
spring-boot-starter-data-jpa
当以其他条件进行查询时:
import com.example.luckymoney.domain.Luckymoney;
import org.springframework.data.jpa.repository.JpaRepository;
import java.math.BigDecimal;
import java.util.List;
public interface LuckmoneyRespository extends JpaRepository {
public List findByMoney(BigDecimal money);
public List findByProducer(String producer);
public List findByProducerAndConsumer(String producer,String consumer);
}
# redis 配置
# redis 数据库索引
spring.redis.database=2
spring.redis.host=123.56.25.127
spring.redis.port=6379
spring.redis.password=123456
# redis 最大连接数
spring.redis.jedis.pool.max-active=1000
# 连接池最大阻塞等待时间 -1 表示没有
spring.redis.jedis.pool.max-wait=-1
# 连接池中最大空闲连接数
spring.redis.jedis.pool.max-idle=10
# 连接池中最小空闲连接数
spring.redis.jedis.pool.min-idle=2
spring.redis.timeout=5000
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-devtools
例子: