springboot(整合多数据源demo,aop,定时任务,异步方法调用,以及获取properties中自定义的变量值)
有这么一个需求 每个部门,需要操作的数据库不同,A部门要将数据放test数据库,B 部门数据 要放在test1数据库 同一个项目 需要整合 多个数据源
上传个demo 方便自己以后回看!!!!!!!!!
https://github.com/SCchengbo/springboot-mybatis-demo.git
- springboot使用AOP 过滤请求:
在pom文件中导入 aop所需要的依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 定义切面
package com.springboot.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect @Component public class testAspect { private Logger logger = LoggerFactory.getLogger(getClass()); @Pointcut("execution(public * com.springboot.controller..*.*(..))") public void testPoint() { } @Before(value = "testPoint()") public void doBefore(JoinPoint joinPoint) throws Throwable { logger.info("前置通知"); } @AfterReturning(returning = "ret", pointcut = "testPoint()") public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 logger.info("RESPONSE : " + ret); }
-
@Pointcut("execution(public * com.springboot.controller..*.*(..))") 所有反问com.springboot.controller包下的请求 都 会被切面拦截 执行路径 http://localhost:8080/select?name=zhangsan
2019-02-11 16:09:22.362 [http-nio-8080-exec-1] INFO com.springboot.aop.testAspect:33 - 前置通知 2019-02-11 16:09:22.366 [http-nio-8080-exec-1] INFO com.springboot.controller.Controller:15 - 接受到请求 2019-02-11 16:09:22.366 [http-nio-8080-exec-1] INFO com.springboot.aop.testAspect:39 - RESPONSE : zhangsan
关于 springboot 使用@Scheduled 做定时任务:
-
package com.springboot.scheduledtasks; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class ScheduledTasks { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { System.out.println("任务1:" + dateFormat.format(new Date())); } }
- 在启动类上面 必须添加@EnableScheduling 注解 不然 定时任务 不起作用
任务1:17:10:22 任务1:17:10:27
-
ScheduledTasks原理:
简要介绍:spring在初始化bean后,通过“postProcessAfterInitialization”拦截到所有的用到“@Scheduled”注解的方法,并解析相应的的注解参数,放入“定时任务列表”等待后续处理;之后再“定时任务列表”中统一执行相应的定时任务(任务为顺序执行,先执行cron,之后再执行fixedRate)。
重要代码如下:
第一步:依次加载所有的实现Scheduled注解的类方法。
第二步:将对应类型的定时器放入相应的“定时任务列表”中。
第三步:执行相应的定时任务。
参考资料:https://blog.csdn.net/gaodebao1/article/details/51789225
-
ScheduledTasks是单线程执行任务,平常 使用定时任务 用的xxl 如果是想要实现多线程 定时任务 则要重写
configureTasks方法
package com.springboot.scheduledtasks; import java.util.concurrent.Executors; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { // 设定一个长度10的定时任务线程池 taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10)); } }
- 测试多线程执行:
package com.springboot.scheduledtasks; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class ScheduledTasks { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { System.out.println("任务1:" + dateFormat.format(new Date())); } @Scheduled(fixedRate = 5000) public void reportCurrentTime1() { System.out.println("任务2:" + dateFormat.format(new Date())); for (;;) { } } }
- 结果:
任务1:17:18:32 任务1:17:18:37 任务1:17:18:42 任务1:17:18:47 任务1:17:18:52
ScheduledTasks平常用的比较少。都是公司内部自己封装的,也有类似xxl此类的定时任务
关于springboot 中 异步方法调用,原来 项目中 希望调用一个 不阻塞的方法的时候,是新创建一个线程 来 执行 需要的逻辑。。springboot 中直接可以使用@Async 标记需要异步执行的方法就可以了
package com.springboot.util; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component public class TestAsync { @Async public void testAsyncMethod() { for (;;) { } } }
@RequestMapping("/testAsync") public void testAsync() { testAsync.testAsyncMethod(); logger.info("测试异步调用"); }
一定需要在启动类中 添加@EnableAsync 注解 不然 异步方法调用 不起作用
springboot如何获取 properties文件中自定义的参数值
package com.springboot.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.springboot.util.TestAsync; @org.springframework.stereotype.Controller public class Controller { private static Logger logger = LoggerFactory.getLogger(Controller.class); @Autowired public TestAsync testAsync; @Value("${time}") public int time; @RequestMapping("/getTime") @ResponseBody public Integer getTime() { return time; }
使用@Value注解
@Value("${time}") 可以获取自定义的数据信息