├── .doc
└── docker
│ ├── docker
│ ├── docker-compose-common.yml
│ ├── docker-compose-kafka.yml
│ └── docker-compose-rocketmq.yml
├── README.md
├── activemq
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ └── activemq
│ │ │ ├── ActivemqApplication.java
│ │ │ ├── config
│ │ │ ├── ActiveMqName.java
│ │ │ └── JmsConfig.java
│ │ │ ├── consumer
│ │ │ ├── queue
│ │ │ │ ├── QueueConsumer.java
│ │ │ │ └── QueueConsumer2.java
│ │ │ └── topic
│ │ │ │ ├── TopicConsumer.java
│ │ │ │ └── TopicConsumer2.java
│ │ │ ├── controller
│ │ │ └── SendControlller.java
│ │ │ └── producer
│ │ │ ├── Sender.java
│ │ │ ├── queue
│ │ │ └── QueueSender.java
│ │ │ └── topic
│ │ │ └── TopicSender.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── activemq
│ └── ActivemqApplicationTests.java
├── case
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ ├── CaseApplication.java
│ │ │ ├── strategy
│ │ │ ├── MallPackageOrderStrategy.java
│ │ │ ├── PackageOrderStrategy.java
│ │ │ ├── PackageOrderStrategyContext.java
│ │ │ └── PartnerPackageOrderStrategy.java
│ │ │ └── template
│ │ │ ├── AbstractPackageOrderService.java
│ │ │ ├── MallPackageOrderService.java
│ │ │ ├── PackageOrder.java
│ │ │ ├── PackageOrderService.java
│ │ │ └── PartnerPackageOrderService.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── ocean
│ ├── strategy
│ └── PackageOrderStrategyContextTest.java
│ └── template
│ └── PackageOrderServiceTest.java
├── common
├── pom.xml
└── src
│ ├── main
│ ├── docker
│ │ └── Dockerfile
│ └── java
│ │ └── com
│ │ └── ocean
│ │ └── common
│ │ ├── BaseResult.java
│ │ ├── ControllerExecutor.java
│ │ ├── ErrorCodeEnum.java
│ │ ├── ResponseResult.java
│ │ └── ServiceException.java
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── lambda
│ └── LambdaTest.java
├── hotchpotch
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ ├── HotchpotchApplication.java
│ │ │ ├── aop
│ │ │ ├── AopTestController.java
│ │ │ └── WebControllerAop.java
│ │ │ ├── redis
│ │ │ ├── client
│ │ │ │ ├── RedisClient.java
│ │ │ │ └── impl
│ │ │ │ │ └── RedisClientImpl.java
│ │ │ └── config
│ │ │ │ └── RedisConfig.java
│ │ │ └── thread
│ │ │ ├── config
│ │ │ └── TaskThreadPoolConfig.java
│ │ │ ├── demo
│ │ │ ├── CurrentThreadDemo.java
│ │ │ ├── MultiRunDemo.java
│ │ │ ├── ThreadDemo.java
│ │ │ └── ThreadNumDemo.java
│ │ │ ├── excute
│ │ │ └── TaskExecutePool.java
│ │ │ └── task
│ │ │ ├── AsyncTask.java
│ │ │ ├── MyCallable.java
│ │ │ ├── MyRunnable.java
│ │ │ └── MyThread.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── redis
│ └── client
│ ├── RedisHashTest.java
│ ├── RedisKeyTest.java
│ ├── RedisListTest.java
│ ├── RedisSetTest.java
│ ├── RedisStringTest.java
│ └── RedisZsetTest.java
├── mybatis
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ ├── MybatisApplication.java
│ │ │ ├── common
│ │ │ └── DatabaseType.java
│ │ │ ├── control
│ │ │ └── UserController.java
│ │ │ ├── dao
│ │ │ ├── NewUserMapper.java
│ │ │ ├── NewUserMapper.xml
│ │ │ ├── OldUserMapper.java
│ │ │ └── OldUserMapper.xml
│ │ │ ├── datasource
│ │ │ ├── DatabaseContextHolder.java
│ │ │ └── MultipleDataSource.java
│ │ │ ├── interceptor
│ │ │ └── DataSourceInterceptor.java
│ │ │ ├── model
│ │ │ ├── NewUser.java
│ │ │ └── OldUser.java
│ │ │ └── service
│ │ │ ├── UserService.java
│ │ │ └── impl
│ │ │ └── UserServiceImpl.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── MybatisApplicationTests.java
├── pom.xml
├── rabbitmq
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ ├── config
│ │ │ ├── DirectRabbitConfig.java
│ │ │ ├── FanoutRabbitConfig.java
│ │ │ ├── RouteRabbitConfig.java
│ │ │ └── TopicRabbitConfig.java
│ │ │ └── ocean
│ │ │ ├── RabbitmqApplication.java
│ │ │ ├── controller
│ │ │ └── SendController.java
│ │ │ ├── listener
│ │ │ ├── fanout
│ │ │ │ └── FanoutReceiver.java
│ │ │ ├── hello
│ │ │ │ └── HelloReceiver.java
│ │ │ ├── object
│ │ │ │ └── ObjectReceiver.java
│ │ │ ├── route
│ │ │ │ └── RouteReceiver.java
│ │ │ ├── topic
│ │ │ │ └── TopicReceiver.java
│ │ │ └── work
│ │ │ │ ├── WorkReceiverOne.java
│ │ │ │ └── WorkReceiverTwo.java
│ │ │ ├── model
│ │ │ ├── Message.java
│ │ │ └── User.java
│ │ │ └── service
│ │ │ ├── SendService.java
│ │ │ └── impl
│ │ │ └── SendServiceImpl.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── RabbitmqApplicationTests.java
├── rocketmq
├── README.md
├── docker-compose-rocketmq.yml
├── pom.xml
├── rmq
│ ├── brokerconf
│ │ └── broker.conf
│ └── readme.md
├── rocket-common
│ ├── pom.xml
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── com
│ │ │ └── ocean
│ │ │ └── rocket
│ │ │ ├── annotation
│ │ │ ├── EnableRocketMQConfig.java
│ │ │ ├── RocketMQConsumer.java
│ │ │ ├── RocketMQKey.java
│ │ │ └── RocketMQProducer.java
│ │ │ ├── base
│ │ │ ├── AbstractMQPushConsumer.java
│ │ │ ├── AbstractRocketMQConsumer.java
│ │ │ └── AbstractRocketMQProducer.java
│ │ │ ├── config
│ │ │ ├── BaseAutoConfig.java
│ │ │ ├── ConsumerAutoConfig.java
│ │ │ ├── ConsumerProperties.java
│ │ │ ├── ProducerAutoConfig.java
│ │ │ └── ProducerProperties.java
│ │ │ ├── constants
│ │ │ └── MessageConstant.java
│ │ │ ├── enums
│ │ │ ├── ConsumeMode.java
│ │ │ └── DelayTimeLevel.java
│ │ │ ├── exception
│ │ │ └── RocketMqException.java
│ │ │ └── hook
│ │ │ ├── ConsumeOneMessageAdvice.java
│ │ │ ├── ProducerShutdownHook.java
│ │ │ └── PushConsumerShutdownHook.java
│ └── target
│ │ ├── maven-archiver
│ │ └── pom.properties
│ │ ├── maven-status
│ │ └── maven-compiler-plugin
│ │ │ ├── compile
│ │ │ └── default-compile
│ │ │ │ ├── createdFiles.lst
│ │ │ │ └── inputFiles.lst
│ │ │ └── testCompile
│ │ │ └── default-testCompile
│ │ │ └── inputFiles.lst
│ │ └── rocket-comon-1.0-SNAPSHOT.jar
├── rocket-consumer
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ └── rocket
│ │ │ ├── RocketMqConsumerApplication.java
│ │ │ └── consumer
│ │ │ └── Consumer.java
│ │ └── resources
│ │ └── application.properties
└── rocket-producer
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ └── rocket
│ │ │ ├── RocketMqProducerApplication.java
│ │ │ └── producer
│ │ │ └── Producer.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── rocket
│ └── producer
│ └── ProducerTest.java
├── solr
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── ocean
│ │ │ └── solr
│ │ │ ├── SolrApplication.java
│ │ │ ├── config
│ │ │ └── SolrConfig.java
│ │ │ ├── controller
│ │ │ └── ProductController.java
│ │ │ ├── dao
│ │ │ └── ProductDao.java
│ │ │ ├── pojo
│ │ │ ├── ProductModel.java
│ │ │ └── ResultModel.java
│ │ │ └── service
│ │ │ └── ProductService.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── com
│ └── ocean
│ └── solr
│ └── SolrApplicationTests.java
└── xxl-job
├── doc
├── XXL-JOB-English-Documentation.md
├── XXL-JOB官方文档.md
├── XXL-JOB架构图.pptx
├── db
│ ├── tables_mysql(备份,请忽略).sql
│ └── tables_xxl_job.sql
└── images
│ ├── cnblog-首页-每日一博-第一.png
│ ├── cnblog-首页-热门动弹-第一.png
│ ├── donate-alipay.jpg
│ ├── donate-paypal.png
│ ├── donate-wechat.png
│ ├── gitee-gvp.jpg
│ ├── img_6yC0.png
│ ├── img_BPLG.png
│ ├── img_EB65.png
│ ├── img_Fgql.png
│ ├── img_Hr2T.png
│ ├── img_Qohm.png
│ ├── img_UDSo.png
│ ├── img_V3vF.png
│ ├── img_Wb2o.png
│ ├── img_Ypik.png
│ ├── img_Z9Qr.png
│ ├── img_ZAhX.png
│ ├── img_ZAsz.png
│ ├── img_dNUJ.png
│ ├── img_eYrv.png
│ ├── img_hIci.png
│ ├── img_iUw0.png
│ ├── img_inc8.png
│ ├── img_jOAU.png
│ ├── img_jrdI.png
│ ├── img_o8HQ.png
│ ├── img_oLlM.png
│ ├── img_tJOq.png
│ ├── img_tvGI.png
│ ├── qq群-一个xxl同学进了58.png
│ ├── xxl-logo.jpg
│ └── xxl-logo.png
├── pom.xml
└── xxl-job-admin
├── Dockerfile
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── xxl
│ │ └── job
│ │ └── admin
│ │ ├── XxlJobAdminApplication.java
│ │ ├── controller
│ │ ├── IndexController.java
│ │ ├── JobApiController.java
│ │ ├── JobCodeController.java
│ │ ├── JobGroupController.java
│ │ ├── JobInfoController.java
│ │ ├── JobLogController.java
│ │ ├── annotation
│ │ │ └── PermessionLimit.java
│ │ ├── interceptor
│ │ │ ├── CookieInterceptor.java
│ │ │ ├── PermissionInterceptor.java
│ │ │ └── WebMvcConfig.java
│ │ └── resolver
│ │ │ └── WebExceptionResolver.java
│ │ ├── core
│ │ ├── conf
│ │ │ ├── XxlJobAdminConfig.java
│ │ │ └── XxlJobDynamicSchedulerConfig.java
│ │ ├── jobbean
│ │ │ └── RemoteHttpJobBean.java
│ │ ├── model
│ │ │ ├── XxlJobGroup.java
│ │ │ ├── XxlJobInfo.java
│ │ │ ├── XxlJobLog.java
│ │ │ ├── XxlJobLogGlue.java
│ │ │ └── XxlJobRegistry.java
│ │ ├── quartz
│ │ │ └── XxlJobThreadPool.java
│ │ ├── route
│ │ │ ├── ExecutorRouteStrategyEnum.java
│ │ │ ├── ExecutorRouter.java
│ │ │ └── strategy
│ │ │ │ ├── ExecutorRouteBusyover.java
│ │ │ │ ├── ExecutorRouteConsistentHash.java
│ │ │ │ ├── ExecutorRouteFailover.java
│ │ │ │ ├── ExecutorRouteFirst.java
│ │ │ │ ├── ExecutorRouteLFU.java
│ │ │ │ ├── ExecutorRouteLRU.java
│ │ │ │ ├── ExecutorRouteLast.java
│ │ │ │ ├── ExecutorRouteRandom.java
│ │ │ │ └── ExecutorRouteRound.java
│ │ ├── schedule
│ │ │ └── XxlJobDynamicScheduler.java
│ │ ├── thread
│ │ │ ├── JobFailMonitorHelper.java
│ │ │ ├── JobRegistryMonitorHelper.java
│ │ │ └── JobTriggerPoolHelper.java
│ │ ├── trigger
│ │ │ ├── TriggerTypeEnum.java
│ │ │ └── XxlJobTrigger.java
│ │ └── util
│ │ │ ├── CookieUtil.java
│ │ │ ├── FtlUtil.java
│ │ │ ├── I18nUtil.java
│ │ │ ├── JacksonUtil.java
│ │ │ └── LocalCacheUtil.java
│ │ ├── dao
│ │ ├── XxlJobGroupDao.java
│ │ ├── XxlJobInfoDao.java
│ │ ├── XxlJobLogDao.java
│ │ ├── XxlJobLogGlueDao.java
│ │ └── XxlJobRegistryDao.java
│ │ └── service
│ │ ├── XxlJobService.java
│ │ └── impl
│ │ ├── AdminBizImpl.java
│ │ └── XxlJobServiceImpl.java
└── resources
│ ├── application.properties
│ ├── i18n
│ ├── message.properties
│ └── message_en.properties
│ ├── logback.xml
│ ├── mybatis-mapper
│ ├── XxlJobGroupMapper.xml
│ ├── XxlJobInfoMapper.xml
│ ├── XxlJobLogGlueMapper.xml
│ ├── XxlJobLogMapper.xml
│ └── XxlJobRegistryMapper.xml
│ ├── quartz.properties
│ ├── static
│ ├── adminlte
│ │ ├── bower_components
│ │ │ ├── Ionicons
│ │ │ │ ├── css
│ │ │ │ │ └── ionicons.min.css
│ │ │ │ └── fonts
│ │ │ │ │ ├── ionicons.eot
│ │ │ │ │ ├── ionicons.svg
│ │ │ │ │ ├── ionicons.ttf
│ │ │ │ │ └── ionicons.woff
│ │ │ ├── PACE
│ │ │ │ ├── pace.min.js
│ │ │ │ └── themes
│ │ │ │ │ └── blue
│ │ │ │ │ └── pace-theme-flash.css
│ │ │ ├── bootstrap-daterangepicker
│ │ │ │ ├── daterangepicker.css
│ │ │ │ └── daterangepicker.js
│ │ │ ├── bootstrap
│ │ │ │ ├── css
│ │ │ │ │ ├── bootstrap.css.map
│ │ │ │ │ └── bootstrap.min.css
│ │ │ │ ├── fonts
│ │ │ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ │ └── js
│ │ │ │ │ └── bootstrap.min.js
│ │ │ ├── datatables.net-bs
│ │ │ │ ├── css
│ │ │ │ │ └── dataTables.bootstrap.min.css
│ │ │ │ └── js
│ │ │ │ │ └── dataTables.bootstrap.min.js
│ │ │ ├── datatables.net
│ │ │ │ └── js
│ │ │ │ │ └── jquery.dataTables.min.js
│ │ │ ├── fastclick
│ │ │ │ └── fastclick.js
│ │ │ ├── font-awesome
│ │ │ │ ├── css
│ │ │ │ │ ├── font-awesome.css.map
│ │ │ │ │ └── font-awesome.min.css
│ │ │ │ └── fonts
│ │ │ │ │ ├── FontAwesome.otf
│ │ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ │ ├── fontawesome-webfont.woff
│ │ │ │ │ └── fontawesome-webfont.woff2
│ │ │ ├── jquery-slimscroll
│ │ │ │ └── jquery.slimscroll.min.js
│ │ │ ├── jquery
│ │ │ │ └── jquery.min.js
│ │ │ └── moment
│ │ │ │ └── moment.min.js
│ │ ├── dist
│ │ │ ├── css
│ │ │ │ ├── AdminLTE.min.css
│ │ │ │ └── skins
│ │ │ │ │ └── _all-skins.min.css
│ │ │ └── js
│ │ │ │ └── adminlte.min.js
│ │ └── plugins
│ │ │ └── iCheck
│ │ │ ├── icheck.min.js
│ │ │ └── square
│ │ │ ├── blue.css
│ │ │ ├── blue.png
│ │ │ └── blue@2x.png
│ ├── favicon.ico
│ ├── js
│ │ ├── common.1.js
│ │ ├── index.js
│ │ ├── jobcode.index.1.js
│ │ ├── jobgroup.index.1.js
│ │ ├── jobinfo.index.1.js
│ │ ├── joblog.detail.1.js
│ │ ├── joblog.index.1.js
│ │ └── login.1.js
│ └── plugins
│ │ ├── codemirror
│ │ ├── addon
│ │ │ └── hint
│ │ │ │ ├── anyword-hint.js
│ │ │ │ ├── show-hint.css
│ │ │ │ └── show-hint.js
│ │ ├── lib
│ │ │ ├── codemirror.css
│ │ │ └── codemirror.js
│ │ └── mode
│ │ │ ├── clike
│ │ │ └── clike.js
│ │ │ ├── javascript
│ │ │ └── javascript.js
│ │ │ ├── php
│ │ │ └── php.js
│ │ │ ├── powershell
│ │ │ └── powershell.js
│ │ │ ├── python
│ │ │ └── python.js
│ │ │ └── shell
│ │ │ └── shell.js
│ │ ├── echarts
│ │ └── echarts.common.min.js
│ │ ├── jquery
│ │ ├── jquery.cookie.js
│ │ └── jquery.validate.min.js
│ │ └── layer
│ │ ├── layer.js
│ │ └── theme
│ │ └── default
│ │ ├── icon-ext.png
│ │ ├── icon.png
│ │ ├── layer.css
│ │ ├── loading-0.gif
│ │ ├── loading-1.gif
│ │ └── loading-2.gif
│ └── templates
│ ├── common
│ ├── common.exception.ftl
│ └── common.macro.ftl
│ ├── help.ftl
│ ├── index.ftl
│ ├── jobcode
│ └── jobcode.index.ftl
│ ├── jobgroup
│ └── jobgroup.index.ftl
│ ├── jobinfo
│ └── jobinfo.index.ftl
│ ├── joblog
│ ├── joblog.detail.ftl
│ └── joblog.index.ftl
│ └── login.ftl
└── test
└── java
└── com
└── xxl
└── job
├── admin
├── controller
│ ├── AbstractSpringMvcTest.java
│ └── JobInfoControllerTest.java
├── dao
│ ├── XxlJobGroupDaoTest.java
│ ├── XxlJobInfoDaoTest.java
│ ├── XxlJobLogDaoTest.java
│ ├── XxlJobLogGlueDaoTest.java
│ └── XxlJobRegistryDaoTest.java
└── util
│ └── I18nUtilTest.java
├── adminbiz
└── AdminBizTest.java
└── executor
└── ExecutorBizTest.java
/.doc/docker/docker:
--------------------------------------------------------------------------------
1 | mvn clean package docker:build -Dmaven.test.skip=true
2 |
3 | mvn clean package docker:build -pl quartz -am -Dmaven.test.skip=true
4 |
5 | mvn clean package -pl quartz -am -Dmaven.test.skip=true
6 |
7 | docker images
8 |
9 | docker rmi
10 |
11 | docker ps
--------------------------------------------------------------------------------
/.doc/docker/docker-compose-common.yml:
--------------------------------------------------------------------------------
1 | version: '1.0'
2 | services:
3 | redis:
4 | image: redis
5 | ports:
6 | - "6379:6379"
--------------------------------------------------------------------------------
/.doc/docker/docker-compose-kafka.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 | services:
3 | zookeeper:
4 | ## 镜像
5 | image: wurstmeister/zookeeper
6 | ## 对外暴露的端口号
7 | ports:
8 | - "2181:2181"
9 | kafka:
10 | ## 镜像
11 | image: wurstmeister/kafka
12 | ## 挂载位置(kafka镜像和宿主机器之间时间保持一直)
13 | volumes:
14 | - /etc/localtime:/etc/localtime
15 | ports:
16 | - "9092:9092"
17 | environment:
18 | ## 修改:宿主机IP
19 | KAFKA_ADVERTISED_HOST_NAME: 10.204.254.43
20 | ## 卡夫卡运行是基于zookeeper的
21 | KAFKA_ZOOKEEPER_CONNECT: 10.204.254.43:2181
22 | kafka-manager:
23 | ## 镜像:开源的web管理kafka集群的界面
24 | image: sheepkiller/kafka-manager
25 | environment:
26 | ## 修改:宿主机IP
27 | ZK_HOSTS: 10.204.254.43
28 | ## 暴露端口
29 | ports:
30 | - "9000:9000"
--------------------------------------------------------------------------------
/.doc/docker/docker-compose-rocketmq.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 |
3 | services:
4 | rmqnamesrv:
5 | image: foxiswho/rocketmq:server-4.5.2
6 | container_name: rmqnamesrv
7 | ports:
8 | - 9876:9876
9 | volumes:
10 | - ./rmq/logs:/opt/logs
11 | - ./rmq/store:/opt/store
12 | environment:
13 | JAVA_OPT_EXT: "-Duser.home=/opt -Xms128m -Xmx128m -Xmn128m"
14 | networks:
15 | rmq:
16 | aliases:
17 | - rmqnamesrv
18 | rmqbroker:
19 | image: foxiswho/rocketmq:broker-4.5.2
20 | container_name: rmqbroker
21 | ports:
22 | - 10909:10909
23 | - 10911:10911
24 | volumes:
25 | - ./rmq/logs:/opt/logs
26 | - ./rmq/store:/opt/store
27 | - ./rmq/brokerconf/broker.conf:/etc/rocketmq/broker.conf
28 | environment:
29 | JAVA_OPT_EXT: "-Duser.home=/opt -server -Xms128m -Xmx128m -Xmn128m"
30 | command: ["/bin/bash","mqbroker","-c","/etc/rocketmq/broker.conf","-n","rmqnamesrv:9876","autoCreateTopicEnable=true"]
31 | depends_on:
32 | - rmqnamesrv
33 | networks:
34 | rmq:
35 | aliases:
36 | - rmqbroker
37 |
38 | rmqconsole:
39 | image: styletang/rocketmq-console-ng
40 | container_name: rmqconsole
41 | ports:
42 | - 8180:8080
43 | environment:
44 | JAVA_OPTS: "-Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
45 | depends_on:
46 | - rmqnamesrv
47 | networks:
48 | rmq:
49 | aliases:
50 | - rmqconsole
51 |
52 | networks:
53 | rmq:
54 | name: rmq
55 | driver: bridge
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SpringBoot
2 | 利用SpringBoot整合ActiveMq、Quartz、Solr、Mybatis
3 |
4 | #Quartz
5 |
6 | Quartz整合H2数据库实现动态管理定时任务
7 |
8 | #Mybatis
9 |
10 | 利用Aop实现数据源的动态切换
11 |
--------------------------------------------------------------------------------
/activemq/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | com.ocean
8 | springboot
9 | 0.0.1-SNAPSHOT
10 |
11 |
12 | activemq
13 | 0.0.1-SNAPSHOT
14 | jar
15 |
16 |
17 |
18 |
19 | org.springframework
20 | spring-jms
21 |
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-activemq
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/ActivemqApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.jms.annotation.EnableJms;
6 |
7 | @SpringBootApplication
8 | @EnableJms
9 | public class ActivemqApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(ActivemqApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/config/ActiveMqName.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.config;
2 |
3 | public class ActiveMqName {
4 | public static final String QUEUE_ONE = "queue1";
5 |
6 | public static final String QUEUE_TWO = "queue2";
7 |
8 | public static final String TOPIC_ONE = "topic1";
9 |
10 | public static final String TOPIC_TWO = "topic2";
11 | }
12 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/config/JmsConfig.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.context.annotation.Primary;
6 | import org.springframework.jms.annotation.EnableJms;
7 | import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
8 | import org.springframework.jms.config.JmsListenerContainerFactory;
9 | import org.springframework.jms.core.JmsTemplate;
10 |
11 | import javax.jms.ConnectionFactory;
12 |
13 | @Configuration
14 | @EnableJms
15 | public class JmsConfig {
16 |
17 | /**
18 | * queue模式的ListenerContainer
19 | *
20 | * @param activeMQConnectionFactory
21 | * @return
22 | */
23 | @Bean
24 | public JmsListenerContainerFactory> jmsListenerContainerQueue(ConnectionFactory activeMQConnectionFactory) {
25 | DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
26 | bean.setConnectionFactory(activeMQConnectionFactory);
27 | return bean;
28 | }
29 |
30 | /**
31 | * topic模式的ListenerContainer
32 | *
33 | * @param activeMQConnectionFactory
34 | * @return
35 | */
36 | @Bean
37 | public JmsListenerContainerFactory> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
38 | DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
39 | bean.setPubSubDomain(true);
40 | bean.setConnectionFactory(activeMQConnectionFactory);
41 | return bean;
42 | }
43 |
44 | @Bean
45 | @Primary
46 | public JmsTemplate jmsQueueTemplate(ConnectionFactory connectionFactory) {
47 | JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
48 | jmsTemplate.setPubSubDomain(false);
49 | return jmsTemplate;
50 | }
51 |
52 | @Bean
53 | public JmsTemplate jmsTopicTemplate(ConnectionFactory connectionFactory) {
54 | JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
55 | jmsTemplate.setPubSubDomain(true);
56 | return jmsTemplate;
57 | }
58 |
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/consumer/queue/QueueConsumer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.consumer.queue;
2 |
3 | import com.ocean.activemq.config.ActiveMqName;
4 | import org.springframework.jms.annotation.JmsListener;
5 | import org.springframework.stereotype.Service;
6 |
7 | @Service
8 | public class QueueConsumer {
9 |
10 | @JmsListener(destination = ActiveMqName.QUEUE_ONE, containerFactory = "jmsListenerContainerQueue")
11 | public void getQueue1(String info) {
12 | System.out.println("listener1成功监听queue1消息队列,传来的值为:" + info);
13 | }
14 |
15 | @JmsListener(destination = ActiveMqName.QUEUE_ONE, containerFactory = "jmsListenerContainerQueue")
16 | public void getQueue2(String info) {
17 | System.out.println("listener2成功监听queue1消息队列,传来的值为:" + info);
18 | }
19 |
20 | @JmsListener(destination = ActiveMqName.QUEUE_TWO, containerFactory = "jmsListenerContainerQueue")
21 | public void getQueue3(String info) {
22 | System.out.println("listener3成功监听queue1消息队列,传来的值为:" + info);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/consumer/queue/QueueConsumer2.java:
--------------------------------------------------------------------------------
1 | //package com.ocean.activemq.consumer.queue;
2 | //
3 | //import org.springframework.stereotype.Service;
4 | //
5 | //import javax.jms.JMSException;
6 | //import javax.jms.Message;
7 | //import javax.jms.MessageListener;
8 | //import javax.jms.TextMessage;
9 | //
10 | //@Service
11 | //public class QueueConsumer2 implements MessageListener {
12 | // public void onMessage(Message message) {
13 | // TextMessage textMessage = (TextMessage) message;
14 | // try {
15 | // System.out
16 | // .println("QueueConsumer2:" + textMessage.getText());
17 | // } catch (JMSException e) {
18 | // e.printStackTrace();
19 | // }
20 | // }
21 | //}
22 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/consumer/topic/TopicConsumer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.consumer.topic;
2 |
3 | import org.springframework.jms.annotation.JmsListener;
4 | import org.springframework.stereotype.Service;
5 |
6 | @Service
7 | public class TopicConsumer {
8 |
9 | @JmsListener(destination = "topic1", containerFactory = "jmsListenerContainerTopic")
10 | public void getTopic1(String info) {
11 | System.out.println("topicListener1成功监听topic1消息队列,传来的值为:" + info);
12 | }
13 |
14 | @JmsListener(destination = "topic1", containerFactory = "jmsListenerContainerTopic")
15 | public void getTopic2(String info) {
16 | System.out.println("topicListener2成功监听topic1消息队列,传来的值为:" + info);
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/consumer/topic/TopicConsumer2.java:
--------------------------------------------------------------------------------
1 | //package com.ocean.activemq.consumer.topic;
2 | //
3 | //import org.springframework.stereotype.Service;
4 | //
5 | //import javax.jms.JMSException;
6 | //import javax.jms.Message;
7 | //import javax.jms.MessageListener;
8 | //import javax.jms.TextMessage;
9 | //
10 | //@Service
11 | //public class TopicConsumer2 implements MessageListener {
12 | //
13 | // public void onMessage(Message message) {
14 | // TextMessage textMessage = (TextMessage) message;
15 | // try {
16 | // System.out
17 | // .println("TopicConsumer2:" + textMessage.getText());
18 | // } catch (JMSException e) {
19 | // e.printStackTrace();
20 | // }
21 | // }
22 | //
23 | //}
24 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/controller/SendControlller.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.controller;
2 |
3 | import com.ocean.activemq.config.ActiveMqName;
4 | import com.ocean.activemq.producer.Sender;
5 | import com.ocean.activemq.producer.queue.QueueSender;
6 | import com.ocean.activemq.producer.topic.TopicSender;
7 | import org.apache.activemq.command.ActiveMQQueue;
8 | import org.apache.activemq.command.ActiveMQTopic;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.web.bind.annotation.GetMapping;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.ResponseBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import javax.jms.Destination;
16 |
17 | @RestController
18 | @RequestMapping
19 | @ResponseBody
20 | public class SendControlller {
21 |
22 | @Autowired
23 | private Sender sender;
24 |
25 | @Autowired
26 | private QueueSender queueSender;
27 |
28 | @Autowired
29 | private TopicSender topicSender;
30 |
31 | @GetMapping(value = "/add/queue")
32 | public void addQueue() {
33 | Destination destination = new ActiveMQQueue(ActiveMqName.QUEUE_ONE);
34 | sender.sendTemple(destination, "success");
35 | }
36 |
37 | @GetMapping(value = "/add/topic")
38 | public void addTopic() {
39 | Destination destination = new ActiveMQTopic(ActiveMqName.TOPIC_ONE);
40 | sender.sendTemple(destination, "success");
41 | }
42 |
43 | @GetMapping(value = "/creat/queue")
44 | public void creatQueue() {
45 | queueSender.send(ActiveMqName.QUEUE_ONE, "success");
46 | }
47 |
48 | @GetMapping(value = "/creat/topic")
49 | public void creatTopic() {
50 | topicSender.send(ActiveMqName.TOPIC_ONE, "success");
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/producer/Sender.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.producer;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.jms.core.JmsMessagingTemplate;
5 | import org.springframework.stereotype.Service;
6 |
7 | import javax.jms.Destination;
8 |
9 | @Service
10 | public class Sender {
11 |
12 | @Autowired
13 | private JmsMessagingTemplate jmsMessagingTemplate;
14 |
15 | public void sendTemple(Destination destination, final String message) {
16 | jmsMessagingTemplate.convertAndSend(destination, message);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/producer/queue/QueueSender.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.producer.queue;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.beans.factory.annotation.Qualifier;
5 | import org.springframework.jms.core.JmsTemplate;
6 | import org.springframework.jms.core.MessageCreator;
7 | import org.springframework.stereotype.Service;
8 |
9 | import javax.jms.JMSException;
10 | import javax.jms.Message;
11 | import javax.jms.Session;
12 |
13 | @Service
14 | public class QueueSender {
15 |
16 | @Autowired
17 | @Qualifier("jmsQueueTemplate")
18 | private JmsTemplate jmsTemplate;
19 |
20 | public void send(String queueName, final String message) {
21 | jmsTemplate.send(queueName, new MessageCreator() {
22 | public Message createMessage(Session session) throws JMSException {
23 | return session.createTextMessage(message);
24 | }
25 | });
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/activemq/src/main/java/com/ocean/activemq/producer/topic/TopicSender.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq.producer.topic;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.beans.factory.annotation.Qualifier;
5 | import org.springframework.jms.core.JmsTemplate;
6 | import org.springframework.jms.core.MessageCreator;
7 | import org.springframework.stereotype.Service;
8 |
9 | import javax.jms.JMSException;
10 | import javax.jms.Message;
11 | import javax.jms.Session;
12 |
13 | @Service
14 | public class TopicSender {
15 | @Autowired
16 | @Qualifier("jmsTopicTemplate")
17 | private JmsTemplate jmsTemplate;
18 |
19 | public void send(String topicName, final String message) {
20 | jmsTemplate.send(topicName, new MessageCreator() {
21 |
22 | public Message createMessage(Session session) throws JMSException {
23 | return session.createTextMessage(message);
24 | }
25 | });
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/activemq/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | #activemq
2 | #spring.activemq.brokerUrl=tcp://127.0.0.1:61616
3 | #spring.activemq.user=admin
4 | #spring.activemq.password=admin
5 | server:
6 | port: 8082
7 | spring:
8 | jms:
9 | pub-sub-domain: true
10 | activemq:
11 | broker-url: tcp://127.0.0.1:61616
12 | user: admin
13 | password: admin
14 | in-memory: false
15 | pool:
16 | enabled: false
17 | packages:
18 | trust-all: true
19 |
20 |
--------------------------------------------------------------------------------
/activemq/src/test/java/com/ocean/activemq/ActivemqApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ocean.activemq;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ActivemqApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/case/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | springboot
7 | com.ocean
8 | 0.0.1-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | case
13 | 0.0.1-SNAPSHOT
14 |
15 |
16 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/CaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class CaseApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(CaseApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/strategy/MallPackageOrderStrategy.java:
--------------------------------------------------------------------------------
1 | package com.ocean.strategy;
2 |
3 | import com.ocean.template.PackageOrder;
4 | import org.springframework.stereotype.Service;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 巢鲜厨包裹订单
10 | * @author 郭大海
11 | */
12 | @Service("mallPackageOrderStrategy")
13 | public class MallPackageOrderStrategy implements PackageOrderStrategy {
14 |
15 | @Override
16 | public void process(List packageOrderList) {
17 | //1、检验包裹
18 | checkPackageOrder(packageOrderList);
19 | //2、匹配包裹订单相关数据
20 | matchPackageOrder(packageOrderList);
21 | //3、生成相应履约单
22 | generatePerformOrder(packageOrderList);
23 | }
24 |
25 | private void checkPackageOrder(List packageOrderList) {
26 | System.out.println("检验包裹");
27 | }
28 |
29 | private void matchPackageOrder(List packageOrderList) {
30 | System.out.println("巢鲜厨电商平台包裹订单,匹配包裹订单相关数据");
31 | }
32 |
33 | private void generatePerformOrder(List packageOrderList) {
34 | System.out.println("巢鲜厨电商平台包裹订单,生成相应履约单");
35 | }
36 | }
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/strategy/PackageOrderStrategy.java:
--------------------------------------------------------------------------------
1 | package com.ocean.strategy;
2 |
3 | import com.ocean.template.PackageOrder;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 包裹订单处理策略接口
9 | *
10 | * @author 郭大海
11 | */
12 | public interface PackageOrderStrategy {
13 |
14 | /**
15 | * 处理包裹订单
16 | *
17 | * @param packageOrderList 包裹订单list
18 | */
19 | void process(List packageOrderList);
20 | }
21 |
22 |
23 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/strategy/PackageOrderStrategyContext.java:
--------------------------------------------------------------------------------
1 | package com.ocean.strategy;
2 |
3 | import com.ocean.template.PackageOrder;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Component;
6 |
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.concurrent.ConcurrentHashMap;
10 |
11 | /**
12 | * 订单包裹处理策略管理器
13 | *
14 | * @author 郭大海
15 | */
16 | @SuppressWarnings("all")
17 | @Component
18 | public class PackageOrderStrategyContext {
19 | /**
20 | * 存储所有实现PackageOrderStrategy接口的Bean
21 | */
22 | private final Map strategyMap = new ConcurrentHashMap<>();
23 |
24 | /**
25 | * 注入所有实现了Strategy接口的Bean
26 | */
27 | @Autowired
28 | public PackageOrderStrategyContext(Map strategyMap) {
29 | this.strategyMap.clear();
30 | strategyMap.forEach((k, v) -> this.strategyMap.put(k, v));
31 | }
32 |
33 | /**
34 | * 处理订单包裹流程
35 | */
36 | public void process(String strategy, List packageOrderList) {
37 | strategyMap.get(strategy).process(packageOrderList);
38 | }
39 | }
40 |
41 |
42 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/strategy/PartnerPackageOrderStrategy.java:
--------------------------------------------------------------------------------
1 | package com.ocean.strategy;
2 |
3 | import com.ocean.template.PackageOrder;
4 | import org.springframework.stereotype.Service;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * 合作商户包裹订单
10 | *
11 | * @author 郭大海
12 | */
13 | @Service("partnerPackageOrderStrategy")
14 | public class PartnerPackageOrderStrategy implements PackageOrderStrategy {
15 |
16 | @Override
17 | public void process(List packageOrderList) {
18 | //1、检验包裹
19 | checkPackageOrder(packageOrderList);
20 | //2、匹配包裹订单相关数据
21 | matchPackageOrder(packageOrderList);
22 | //3、生成相应履约单
23 | generatePerformOrder(packageOrderList);
24 | //4、发送邮件给合作商户
25 | sendEmail(packageOrderList);
26 | }
27 |
28 | private void checkPackageOrder(List packageOrderList) {
29 | System.out.println("检验包裹");
30 | }
31 |
32 | private void matchPackageOrder(List packageOrderList) {
33 | System.out.println("巢鲜厨电商平台包裹订单,匹配包裹订单相关数据");
34 | }
35 |
36 | private void generatePerformOrder(List packageOrderList) {
37 | System.out.println("巢鲜厨电商平台包裹订单,生成相应履约单");
38 | }
39 |
40 | private void sendEmail(List packageOrderList) {
41 | System.out.println("发送邮件通知合作商户");
42 | }
43 | }
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/template/AbstractPackageOrderService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * 包裹订单合单处理
7 | *
8 | * @author 郭大海
9 | */
10 | @SuppressWarnings("all")
11 | public abstract class AbstractPackageOrderService implements PackageOrderService {
12 | /**
13 | * 处理包裹订单流程
14 | * @param packageOrderList 包裹订单list
15 | */
16 | @Override
17 | public void process(List packageOrderList) {
18 | checkPackageOrder(packageOrderList);
19 | matchPackageOrder(packageOrderList);
20 | generatePerformOrder(packageOrderList);
21 | }
22 |
23 | /**
24 | * 检验包裹订单
25 | * @param packageOrderList 包裹订单list
26 | */
27 | void checkPackageOrder(List packageOrderList) {
28 | System.out.println("同样的检验");
29 | }
30 |
31 | /**
32 | * 匹配关联信息
33 | * @param packageOrderList 包裹订单list
34 | */
35 | abstract void matchPackageOrder(List packageOrderList);
36 | /**
37 | * 生成相关履约单
38 | * @param packageOrderList 包裹订单list
39 | */
40 | abstract void generatePerformOrder(List packageOrderList);
41 | }
42 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/template/MallPackageOrderService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | import org.springframework.stereotype.Service;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 巢鲜厨电商平台包裹订单
9 | *
10 | * @author 郭大海
11 | */
12 | @Service("mallPackageOrderService")
13 | public class MallPackageOrderService extends AbstractPackageOrderService {
14 |
15 | @Override
16 | void matchPackageOrder(List packageOrderList) {
17 | System.out.println("巢鲜厨电商平台包裹订单,匹配包裹订单相关数据");
18 | }
19 |
20 | @Override
21 | void generatePerformOrder(List packageOrderList) {
22 | System.out.println("巢鲜厨电商平台包裹订单,生成相应履约单");
23 | }
24 | }
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/template/PackageOrder.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | public class PackageOrder {
4 | }
5 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/template/PackageOrderService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * 包裹订单处理
7 | *
8 | * @author 郭大海
9 | */
10 | public interface PackageOrderService {
11 |
12 | /**
13 | * 处理包裹订单
14 | *
15 | * @param packageOrderList 包裹订单list
16 | */
17 | void process(List packageOrderList);
18 | }
19 |
20 |
21 |
--------------------------------------------------------------------------------
/case/src/main/java/com/ocean/template/PartnerPackageOrderService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | import org.springframework.stereotype.Service;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 合作商户包裹订单
9 | *
10 | * @author 郭大海
11 | */
12 | @Service("partnerPackageOrderService")
13 | public class PartnerPackageOrderService extends AbstractPackageOrderService {
14 |
15 | @Override
16 | void matchPackageOrder(List packageOrderList) {
17 | System.out.println("合作商户包裹订单,匹配包裹订单相关数据");
18 | }
19 |
20 | @Override
21 | void generatePerformOrder(List packageOrderList) {
22 | System.out.println("合作商户包裹订单,生成相应履约单");
23 | }
24 | }
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/case/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8000
2 |
--------------------------------------------------------------------------------
/case/src/test/java/com/ocean/strategy/PackageOrderStrategyContextTest.java:
--------------------------------------------------------------------------------
1 | package com.ocean.strategy;
2 |
3 | import com.ocean.CaseApplication;
4 | import com.ocean.template.PackageOrder;
5 | import org.assertj.core.util.Lists;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.test.context.junit4.SpringRunner;
11 |
12 | import java.util.List;
13 |
14 | @RunWith(SpringRunner.class)
15 | @SpringBootTest(classes = CaseApplication.class)
16 | public class PackageOrderStrategyContextTest {
17 |
18 | @Autowired
19 | private PackageOrderStrategyContext packageOrderStrategyConText;
20 |
21 |
22 | @Test
23 | public void test() {
24 | List packageOrderList = Lists.newArrayList();
25 | String strategy = "mallPackageOrderStrategy";
26 | process(strategy, packageOrderList);
27 | System.out.println("===================分割线===================");
28 | strategy = "partnerPackageOrderStrategy";
29 | process(strategy, packageOrderList);
30 | }
31 |
32 | /**
33 | * 订单包裹处理
34 | */
35 | private void process(String strategy, List packageOrderList) {
36 | packageOrderStrategyConText.process(strategy, packageOrderList);
37 | }
38 |
39 |
40 |
41 |
42 | }
--------------------------------------------------------------------------------
/case/src/test/java/com/ocean/template/PackageOrderServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.ocean.template;
2 |
3 | import com.ocean.CaseApplication;
4 | import org.assertj.core.util.Lists;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import javax.annotation.Resource;
11 |
12 | @RunWith(SpringRunner.class)
13 | @SpringBootTest(classes = CaseApplication.class)
14 | public class PackageOrderServiceTest {
15 |
16 | @Resource
17 | private PackageOrderService mallPackageOrderService;
18 |
19 | @Resource
20 | private PackageOrderService partnerPackageOrderService;
21 |
22 | /**
23 | * 巢鲜厨订单包裹处理
24 | */
25 | @Test
26 | public void mallPackageOrder() {
27 | mallPackageOrderService.process(Lists.newArrayList());
28 | }
29 |
30 | /**
31 | * 合作商户订单包裹处理
32 | */
33 | @Test
34 | public void partnerPackageOrder() {
35 | partnerPackageOrderService.process(Lists.newArrayList());
36 | }
37 | }
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | com.ocean
8 | springboot
9 | 0.0.1-SNAPSHOT
10 |
11 |
12 | common
13 | 0.0.1-SNAPSHOT
14 | jar
15 |
16 | common
17 | 公共模块
18 |
19 |
20 |
--------------------------------------------------------------------------------
/common/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | VOLUME /tmp
3 | ADD quartz-0.0.1-SNAPSHOT.jar app.jar
4 | RUN bash -c 'touch /app.jar'
5 | EXPOSE 9000
6 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
--------------------------------------------------------------------------------
/common/src/main/java/com/ocean/common/BaseResult.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author guodahai
7 | * @version 2018/4/17 上午10:23
8 | */
9 | public class BaseResult implements Serializable {
10 |
11 | private static final long serialVersionUID = 3962215109252373857L;
12 |
13 | private boolean success = true;
14 | private Integer errorCode = 200;
15 | private String errorMessage;
16 |
17 | public BaseResult() {
18 |
19 | }
20 |
21 | public boolean isSuccess() {
22 | return this.success;
23 | }
24 |
25 | public void setSuccess(boolean success) {
26 | this.success = success;
27 | }
28 |
29 | public Integer getErrorCode() {
30 | return this.errorCode;
31 | }
32 |
33 | public void setErrorCode(Integer errorCode) {
34 | this.errorCode = errorCode;
35 | }
36 |
37 | public String getErrorMessage() {
38 | return this.errorMessage;
39 | }
40 |
41 | public void setErrorMessage(String errorMessage) {
42 | this.errorMessage = errorMessage;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ocean/common/ControllerExecutor.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | /**
4 | * 控制层执行抽象类
5 | *
6 | * @author guodahai
7 | * @version 2018/4/17 上午11:08
8 | */
9 | public abstract class ControllerExecutor {
10 |
11 | private T[] param;
12 |
13 | public ControllerExecutor(T... param) {
14 | this.param = param;
15 | }
16 |
17 | public abstract void checkParam(T... param) throws ServiceException;
18 |
19 | public abstract R executeService(T... param) throws ServiceException;
20 |
21 | public ResponseResult execute(T... param) throws ServiceException {
22 | ResponseResult result = new ResponseResult<>();
23 | try {
24 | R r = executeService(param);
25 | if (r instanceof Boolean) {
26 | Boolean b = (Boolean) r;
27 | result.setSuccess(b);
28 | } else {
29 | result.setData(r);
30 | }
31 | } catch (ServiceException e) {
32 | result.setSuccess(false);
33 | result.setErrorCode(e.getErrorCode().getCode());
34 | result.setErrorMessage(e.getErrorMsg());
35 | }
36 | return result;
37 | }
38 |
39 | public T[] getParam() {
40 | return param;
41 | }
42 |
43 | public void setParam(T[] param) {
44 | this.param = param;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ocean/common/ErrorCodeEnum.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | /**
4 | * 错误码定义
5 | *
6 | * @author guodahai
7 | * @version 2018/4/17 上午10:52
8 | */
9 | public enum ErrorCodeEnum {
10 |
11 | P01(417, "参数传入不符合规则"),
12 | Q01(418, "数据库查询失败"),
13 | U01(418, "数据库更新失败"),
14 | I01(418, "数据库插入失败"),
15 | D01(418, "数据库删除失败"),
16 | P99(500, "系统异常"),
17 | QUA01(419, "quartz异常");
18 |
19 | private Integer code;
20 | private String desc;
21 |
22 | ErrorCodeEnum(Integer code, String desc) {
23 | this.code = code;
24 | this.desc = desc;
25 | }
26 |
27 | public String getDesc() {
28 | return desc;
29 | }
30 |
31 | public void setDesc(String desc) {
32 | this.desc = desc;
33 | }
34 |
35 | public Integer getCode() {
36 | return code;
37 | }
38 |
39 | public void setCode(Integer code) {
40 | this.code = code;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ocean/common/ResponseResult.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | /**
4 | * 数据返回Result
5 | *
6 | * @author guodahai
7 | * @version 2018/4/17 上午11:19
8 | */
9 | public class ResponseResult extends BaseResult {
10 | private T data;
11 |
12 | public T getData() {
13 | return data;
14 | }
15 |
16 | public void setData(T data) {
17 | this.data = data;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ocean/common/ServiceException.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | /**
4 | * 自定义异常
5 | *
6 | * @author guodahai
7 | * @version 2018/4/17 上午10:43
8 | */
9 | public class ServiceException extends RuntimeException {
10 |
11 | private static final long serialVersionUID = -2396422934408894887L;
12 |
13 | private ErrorCodeEnum errorCode;
14 |
15 | private String errorMsg;
16 |
17 | /**
18 | * 带错误码的构造函数
19 | *
20 | * @param errorCode
21 | */
22 | public ServiceException(ErrorCodeEnum errorCode, String errorMsg) {
23 | this.errorCode = errorCode;
24 | this.setErrorMsg(errorMsg);
25 | }
26 |
27 | public ServiceException(String message) {
28 | super(message);
29 | }
30 |
31 | /**
32 | * 带错误码的构造函数
33 | *
34 | * @param errorCode
35 | */
36 | public ServiceException(ErrorCodeEnum errorCode) {
37 | super(errorCode.getDesc());
38 | this.errorCode = errorCode;
39 | }
40 |
41 | /**
42 | * 获取错误码
43 | *
44 | * @return
45 | */
46 | public ErrorCodeEnum getErrorEnum() {
47 | return errorCode;
48 | }
49 |
50 | public String getErrorMsg() {
51 | return errorMsg;
52 | }
53 |
54 | public void setErrorMsg(String errorMsg) {
55 | this.errorMsg = errorMsg;
56 | }
57 |
58 | public ErrorCodeEnum getErrorCode() {
59 | return errorCode;
60 | }
61 |
62 | public void setErrorCode(ErrorCodeEnum errorCode) {
63 | this.errorCode = errorCode;
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/hotchpotch/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | hotchpotch
7 | 1.0-SNAPSHOT
8 | jar
9 |
10 |
11 | com.ocean
12 | springboot
13 | 0.0.1-SNAPSHOT
14 |
15 |
16 |
17 |
18 | com.ocean
19 | common
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-data-redis
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | com.google.collections
33 | google-collections
34 |
35 |
36 | com.alibaba
37 | druid
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/HotchpotchApplication.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.scheduling.annotation.EnableAsync;
6 |
7 | /**
8 | * 启动类
9 | *
10 | * @author guodahai
11 | */
12 | @SpringBootApplication
13 | @EnableAsync
14 | public class HotchpotchApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(HotchpotchApplication.class, args);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/aop/AopTestController.java:
--------------------------------------------------------------------------------
1 | package com.aop;
2 |
3 |
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | /**
8 | *
9 | * @author guodahai
10 | * @date 2016/11/19
11 | */
12 | @RestController
13 | @RequestMapping("/aop")
14 | public class AopTestController {
15 |
16 | @RequestMapping("/testBeforeService.do")
17 | public String testBeforeService(String key, String value) {
18 |
19 | return "key=" + key + " value=" + value;
20 | }
21 |
22 | @RequestMapping("/testAfterReturning.do")
23 | public String testAfterReturning(String key) {
24 |
25 | return "key=: " + key;
26 | }
27 |
28 | @RequestMapping("/testAfterReturning01.do")
29 | public Integer testAfterReturning01(Integer key) {
30 |
31 | return key;
32 | }
33 |
34 | @RequestMapping("/testAfterThrowing.do")
35 | public String testAfterThrowing(String key) {
36 |
37 | throw new NullPointerException();
38 | }
39 |
40 | @RequestMapping("/testAfter.do")
41 | public String testAfter(String key) {
42 |
43 | throw new NullPointerException();
44 | }
45 |
46 | @RequestMapping("/testAfter02.do")
47 | public String testAfter02(String key) {
48 |
49 | return key;
50 | }
51 |
52 | @RequestMapping("/testAroundService.do")
53 | public String testAroundService(String key) {
54 |
55 | return "环绕通知:" + key;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/config/TaskThreadPoolConfig.java:
--------------------------------------------------------------------------------
1 | package com.thread.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Configuration;
5 |
6 | /**
7 | * 连接池配置类
8 | *
9 | * @author guodahai
10 | * @version 2018/4/11 下午2:05
11 | */
12 | @Configuration
13 | public class TaskThreadPoolConfig {
14 |
15 | @Value("${task.core.pool.size}")
16 | private int corePoolSize;
17 |
18 | @Value("${task.max.pool.size}")
19 | private int maxPoolSize;
20 |
21 | @Value("${task.queue.capacity}")
22 | private int keepAliveSeconds;
23 |
24 | @Value("${task.keep.alive.seconds}")
25 | private int queueCapacity;
26 |
27 | public int getCorePoolSize() {
28 | return corePoolSize;
29 | }
30 |
31 | public void setCorePoolSize(int corePoolSize) {
32 | this.corePoolSize = corePoolSize;
33 | }
34 |
35 | public int getMaxPoolSize() {
36 | return maxPoolSize;
37 | }
38 |
39 | public void setMaxPoolSize(int maxPoolSize) {
40 | this.maxPoolSize = maxPoolSize;
41 | }
42 |
43 | public int getKeepAliveSeconds() {
44 | return keepAliveSeconds;
45 | }
46 |
47 | public void setKeepAliveSeconds(int keepAliveSeconds) {
48 | this.keepAliveSeconds = keepAliveSeconds;
49 | }
50 |
51 | public int getQueueCapacity() {
52 | return queueCapacity;
53 | }
54 |
55 | public void setQueueCapacity(int queueCapacity) {
56 | this.queueCapacity = queueCapacity;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/demo/CurrentThreadDemo.java:
--------------------------------------------------------------------------------
1 | package com.thread.demo;
2 |
3 | public class CurrentThreadDemo {
4 | public static void main(String[] args) throws InterruptedException {
5 | new Thread("custom thread"){
6 | @Override
7 | public void run() {
8 | System.out.println("当前线程:"+Thread.currentThread().getName());
9 | }
10 | }.start();
11 | Thread.sleep(100);
12 | System.out.println("当前线程:"+Thread.currentThread().getName());
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/demo/MultiRunDemo.java:
--------------------------------------------------------------------------------
1 | package com.thread.demo;
2 |
3 | public class MultiRunDemo {
4 | public static void main(String[] args) {
5 | //传入了Runnable实现类
6 | new Thread(new MyRunnable()){
7 | @Override
8 | public void run() {
9 | System.out.println("我是直接覆写Thread类run方法的代码...");
10 | }
11 | }.start();
12 | }
13 | static class MyRunnable implements Runnable{
14 | @Override
15 | public void run() {
16 | System.out.println("我是实现Runnable接口的对象中的run方法的代码...");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/demo/ThreadDemo.java:
--------------------------------------------------------------------------------
1 | package com.thread.demo;
2 |
3 |
4 | /**
5 | * 演示多个线程可以并发执行的案例
6 | */
7 | public class ThreadDemo {
8 | public static void main(String[] args) {
9 | //创建一个线程对象,覆盖其run方法,传入参数为线程的名字
10 | Thread t1 = new Thread() {
11 | @Override
12 | public void run() {
13 | for (int i = 1; i <= 1000; i++) {
14 | System.out.println("自定义线程循环:" + i + "次");
15 | }
16 | }
17 | };
18 | //调用start方法启动线程
19 | t1.start();
20 | for (int i = 1; i <= 1000; i++) {
21 | System.out.println("主线程循环:" + i + "次");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/demo/ThreadNumDemo.java:
--------------------------------------------------------------------------------
1 | package com.thread.demo;
2 |
3 | import java.lang.management.ManagementFactory;
4 | import java.lang.management.ThreadInfo;
5 | import java.lang.management.ThreadMXBean;
6 |
7 | public class ThreadNumDemo {
8 | public static void main(String[] args) {
9 | ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
10 | ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
11 | for (ThreadInfo threadInfo : threadInfos) {
12 | System.out.println(threadInfo.getThreadId() + "-" + threadInfo.getThreadName());
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/task/AsyncTask.java:
--------------------------------------------------------------------------------
1 | package com.thread.task;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.scheduling.annotation.Async;
6 | import org.springframework.stereotype.Component;
7 |
8 |
9 | /**
10 | * @author guodahai
11 | * @version 2018/4/11 下午2:24
12 | */
13 | @Component
14 | public class AsyncTask {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(AsyncTask.class);
17 |
18 | @Async("myTaskAsyncPool")
19 | public void task(int i) {
20 | logger.info("Task:{},thread", i);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/task/MyCallable.java:
--------------------------------------------------------------------------------
1 | package com.thread.task;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 |
7 | import java.util.concurrent.Callable;
8 |
9 | /**
10 | * @author guodahai
11 | * @version 2018/4/11 下午4:18
12 | */
13 | public class MyCallable implements Callable {
14 |
15 | private final Logger logger = LoggerFactory.getLogger(MyCallable.class);
16 |
17 | @Autowired
18 | private Integer i;
19 |
20 | public MyCallable(Integer i) {
21 | this.i = i;
22 | }
23 |
24 | @Override
25 | public Boolean call() throws Exception {
26 | logger.info("Task:{},thread", i);
27 | return true;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/task/MyRunnable.java:
--------------------------------------------------------------------------------
1 | package com.thread.task;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | * @author guodahai
8 | * @version 2018/4/11 下午4:12
9 | */
10 | public class MyRunnable implements Runnable {
11 |
12 | private final Logger logger = LoggerFactory.getLogger(MyRunnable.class);
13 |
14 | private int i;
15 |
16 | public MyRunnable(int i) {
17 | this.i = i;
18 | }
19 |
20 | @Override
21 | public void run() {
22 | logger.info("Task:{},thread", i);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/java/com/thread/task/MyThread.java:
--------------------------------------------------------------------------------
1 | package com.thread.task;
2 |
3 |
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | /**
8 | * @author guodahai
9 | * @version 2018/4/11 下午3:53
10 | */
11 | public class MyThread extends Thread {
12 |
13 | private final Logger logger = LoggerFactory.getLogger(MyThread.class);
14 |
15 | private int i;
16 |
17 | public MyThread(int i) {
18 | this.i = i;
19 | }
20 |
21 | @Override
22 | public void run() {
23 | logger.info("Task:{},thread", i);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/hotchpotch/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #核心线程数
2 | task.core.pool.size=5
3 | #最大线程数
4 | task.max.pool.size=50
5 | #队列最大长度
6 | task.queue.capacity=1000
7 | #线程池维护线程所允许的空闲时间,默认为60s
8 | task.keep.alive.seconds=60
9 | #redis
10 | # Redis数据库索引(默认为0)
11 | spring.redis.database=0
12 | # Redis服务器地址
13 | spring.redis.host=106.14.143.39
14 | # Redis服务器连接端口
15 | spring.redis.port=6379
16 | # Redis服务器连接密码(默认为空)
17 | spring.redis.password=root
18 | # 连接池最大连接数(使用负值表示没有限制)
19 | spring.redis.pool.max-active=8
20 | # 连接池最大阻塞等待时间(使用负值表示没有限制)
21 | spring.redis.pool.max-wait=-1
22 | # 连接池中的最大空闲连接
23 | spring.redis.pool.max-idle=8
24 | # 连接池中的最小空闲连接
25 | spring.redis.pool.min-idle=0
26 | # 连接超时时间(毫秒)
27 | spring.redis.timeout=1000
28 | #spring.session.store-type=redis
--------------------------------------------------------------------------------
/hotchpotch/src/test/java/com/redis/client/RedisStringTest.java:
--------------------------------------------------------------------------------
1 | package com.redis.client;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.data.redis.core.RedisTemplate;
8 | import org.springframework.data.redis.core.StringRedisTemplate;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | /**
12 | * redis测试
13 | *
14 | * @author guodahai
15 | * @version 2019/3/29 16:16
16 | */
17 | @RunWith(SpringRunner.class)
18 | @SpringBootTest
19 | public class RedisStringTest {
20 | /**
21 | * RedisTemplate和StringRedisTemplate的区别:
22 | * 1. 两者的关系是StringRedisTemplate继承RedisTemplate。
23 | * 2. 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
24 | * 3. SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
25 | * StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
26 | * RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
27 | */
28 | @Autowired
29 | private RedisTemplate redisTemplate;
30 | @Autowired
31 | private StringRedisTemplate stringRedisTemplate;
32 |
33 | /**
34 | * SET name "gdh" result: "name":"gdh"
35 | */
36 | @Test
37 | public void set() {
38 | redisTemplate.opsForValue().set("name", "gdh");
39 | }
40 |
41 | /**
42 | * SET name "gdh" result: name:"gdh"
43 | */
44 | @Test
45 | public void set2() {
46 | stringRedisTemplate.opsForValue().set("name", "gdh");
47 | }
48 |
49 | /**
50 | * GET name 获取指定 key 的值;
51 | */
52 | @Test
53 | public void get() {
54 | Object value = redisTemplate.opsForValue().get("name");
55 | System.out.println(value);
56 | }
57 |
58 | /**
59 | * GETRANGE key start end 返回 key 中字符串值的子字符;
60 | */
61 | @Test
62 | public void getRange() {
63 | Object value = redisTemplate.opsForValue().get("name", 0, 1);
64 | System.out.println(value);
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/mybatis/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | mybatis
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 |
11 | com.ocean
12 | springboot
13 | 0.0.1-SNAPSHOT
14 |
15 |
16 |
17 |
18 |
19 | org.mybatis.spring.boot
20 | mybatis-spring-boot-starter
21 |
22 |
23 |
24 |
25 | mysql
26 | mysql-connector-java
27 |
28 |
29 |
30 | com.alibaba
31 | druid
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/MybatisApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class MybatisApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(MybatisApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/common/DatabaseType.java:
--------------------------------------------------------------------------------
1 | package com.ocean.common;
2 |
3 | /**
4 | * 数据源key常量
5 | *
6 | * @author guodahai
7 | * @version 2018/4/12
8 | */
9 | public enum DatabaseType {
10 | /**
11 | * 新数据源
12 | */
13 | NEW_DATASOURCE,
14 | /**
15 | * 旧数据源
16 | */
17 | OLD_DATASOURCE
18 | }
19 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/control/UserController.java:
--------------------------------------------------------------------------------
1 | package com.ocean.control;
2 |
3 |
4 | import com.ocean.model.NewUser;
5 | import com.ocean.model.OldUser;
6 | import com.ocean.service.UserService;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.ResponseBody;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | import javax.websocket.server.PathParam;
14 |
15 | /**
16 | * @author guodahai
17 | * @version 2018/4/12 下午5:14
18 | */
19 | @RestController
20 | @RequestMapping("user")
21 | @ResponseBody
22 | public class UserController {
23 |
24 | @Autowired
25 | private UserService userService;
26 |
27 | @GetMapping("/new")
28 | public NewUser queryNewUser(@PathParam("id") Integer id) {
29 | return userService.queryNewUser(id);
30 | }
31 |
32 | @GetMapping("/old")
33 | public OldUser queryOldUser(@PathParam("id") Integer id) {
34 | return userService.queryOldUser(id);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/dao/NewUserMapper.java:
--------------------------------------------------------------------------------
1 | package com.ocean.dao;
2 |
3 | import com.ocean.model.NewUser;
4 | import org.apache.ibatis.annotations.Mapper;
5 |
6 | /**
7 | * @author guodahai
8 | * @version 2018/4/12 下午4:45
9 | */
10 | @Mapper
11 | public interface NewUserMapper {
12 |
13 | NewUser queryById(Integer id);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/dao/NewUserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | id,
14 | name,
15 | age,
16 | sex
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/dao/OldUserMapper.java:
--------------------------------------------------------------------------------
1 | package com.ocean.dao;
2 |
3 | import com.ocean.model.OldUser;
4 | import org.apache.ibatis.annotations.Mapper;
5 |
6 | /**
7 | * @author guodahai
8 | * @version 2018/4/12 下午4:43
9 | */
10 | @Mapper
11 | public interface OldUserMapper {
12 |
13 | OldUser queryById(Integer id);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/dao/OldUserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | id,
14 | name,
15 | age,
16 | sex
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/datasource/DatabaseContextHolder.java:
--------------------------------------------------------------------------------
1 | package com.ocean.datasource;
2 |
3 | import com.ocean.common.DatabaseType;
4 |
5 | /**
6 | * 数据源容器
7 | *
8 | * @author guodahai
9 | * @version 2018/4/12
10 | */
11 | public class DatabaseContextHolder {
12 |
13 | private static final ThreadLocal contextHolder = ThreadLocal.withInitial(() -> DatabaseType.NEW_DATASOURCE);
14 |
15 | public static void setDatabaseType(DatabaseType type) {
16 | contextHolder.set(type);
17 | }
18 |
19 | public static DatabaseType getDatabaseType() {
20 | return contextHolder.get();
21 | }
22 |
23 | public static void resetDatabaseType() {
24 | contextHolder.set(DatabaseType.NEW_DATASOURCE);
25 | }
26 |
27 | public static void clearDatabaseType() {
28 | contextHolder.remove();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/datasource/MultipleDataSource.java:
--------------------------------------------------------------------------------
1 | package com.ocean.datasource;
2 |
3 | import com.ocean.common.DatabaseType;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
7 |
8 | /**
9 | * 动态数据源
10 | *
11 | * @author guodahai
12 | * @version 2018/4/12 下午3:01
13 | */
14 | public class MultipleDataSource extends AbstractRoutingDataSource {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(MultipleDataSource.class);
17 |
18 | /**
19 | * 设置进去的当前线程数据源进行数据源切换
20 | *
21 | * @return 数据源名称
22 | */
23 | @Override
24 | protected Object determineCurrentLookupKey() {
25 | DatabaseType databaseType = DatabaseContextHolder.getDatabaseType();
26 | logger.info("当前线程数据源----------------:{}", databaseType);
27 | return databaseType;
28 | }
29 |
30 | @Override
31 | public java.util.logging.Logger getParentLogger() {
32 | return null;
33 | }
34 | }
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/interceptor/DataSourceInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.ocean.interceptor;
2 |
3 | import com.ocean.common.DatabaseType;
4 | import com.ocean.datasource.DatabaseContextHolder;
5 | import org.aspectj.lang.annotation.Aspect;
6 | import org.aspectj.lang.annotation.Before;
7 | import org.aspectj.lang.annotation.Pointcut;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.stereotype.Component;
11 |
12 | /**
13 | * @author guodahai
14 | * @version 2018/4/13 上午9:58
15 | */
16 | @Component
17 | @Aspect
18 | public class DataSourceInterceptor {
19 |
20 | private Logger logger = LoggerFactory.getLogger(DataSourceInterceptor.class);
21 |
22 | @Pointcut("execution(* com.ocean.dao.NewUserMapper.*(..))")
23 | public void newDataSource() {
24 | }
25 |
26 | @Before("newDataSource()")
27 | public void setNewDataSource() {
28 | DatabaseContextHolder.setDatabaseType(DatabaseType.NEW_DATASOURCE);
29 | logger.info("当前数据源为:{}", DatabaseType.NEW_DATASOURCE);
30 | }
31 |
32 | @Pointcut("execution(* com.ocean.dao.OldUserMapper.*(..))")
33 | public void oldDataSource() {
34 | }
35 |
36 | @Before("oldDataSource()")
37 | public void setoldDataSource() {
38 | DatabaseContextHolder.setDatabaseType(DatabaseType.OLD_DATASOURCE);
39 | logger.info("当前数据源为:{}", DatabaseType.OLD_DATASOURCE);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/model/NewUser.java:
--------------------------------------------------------------------------------
1 | package com.ocean.model;
2 |
3 | /**
4 | * 新的用户信息
5 | *
6 | * @author guodahai
7 | * @version 2018/4/12 下午4:46
8 | */
9 | public class NewUser {
10 | /**
11 | * 用户id
12 | */
13 | private Integer id;
14 | /**
15 | * 用户姓名
16 | */
17 | private String name;
18 | /**
19 | * 用户年龄
20 | */
21 | private Integer age;
22 | /**
23 | * 用户性别
24 | */
25 | private String sex;
26 |
27 | public Integer getId() {
28 | return id;
29 | }
30 |
31 | public void setId(Integer id) {
32 | this.id = id;
33 | }
34 |
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | public void setName(String name) {
40 | this.name = name;
41 | }
42 |
43 | public Integer getAge() {
44 | return age;
45 | }
46 |
47 | public void setAge(Integer age) {
48 | this.age = age;
49 | }
50 |
51 | public String getSex() {
52 | return sex;
53 | }
54 |
55 | public void setSex(String sex) {
56 | this.sex = sex;
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "NewUserDTO{" +
62 | "id=" + id +
63 | ", name='" + name + '\'' +
64 | ", age=" + age +
65 | ", sex='" + sex + '\'' +
66 | '}';
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/model/OldUser.java:
--------------------------------------------------------------------------------
1 | package com.ocean.model;
2 |
3 | /**
4 | * 新的用户信息
5 | *
6 | * @author guodahai
7 | * @version 2018/4/12 下午4:46
8 | */
9 | public class OldUser {
10 | /**
11 | * 用户id
12 | */
13 | private Integer id;
14 | /**
15 | * 用户姓名
16 | */
17 | private String name;
18 | /**
19 | * 用户年龄
20 | */
21 | private Integer age;
22 | /**
23 | * 用户性别
24 | */
25 | private String sex;
26 |
27 | public Integer getId() {
28 | return id;
29 | }
30 |
31 | public void setId(Integer id) {
32 | this.id = id;
33 | }
34 |
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | public void setName(String name) {
40 | this.name = name;
41 | }
42 |
43 | public Integer getAge() {
44 | return age;
45 | }
46 |
47 | public void setAge(Integer age) {
48 | this.age = age;
49 | }
50 |
51 | public String getSex() {
52 | return sex;
53 | }
54 |
55 | public void setSex(String sex) {
56 | this.sex = sex;
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "NewUserDTO{" +
62 | "id=" + id +
63 | ", name='" + name + '\'' +
64 | ", age=" + age +
65 | ", sex='" + sex + '\'' +
66 | '}';
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.service;
2 |
3 | import com.ocean.model.NewUser;
4 | import com.ocean.model.OldUser;
5 |
6 | /**
7 | * @author guodahai
8 | * @version 2018/4/12 下午4:51
9 | */
10 | public interface UserService {
11 | /**
12 | * 查询新库用户信息
13 | *
14 | * @param id
15 | * @return
16 | */
17 | public NewUser queryNewUser(Integer id);
18 |
19 | /**
20 | * 查询旧库用户信息
21 | *
22 | * @param id
23 | * @return
24 | */
25 | public OldUser queryOldUser(Integer id);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/mybatis/src/main/java/com/ocean/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.ocean.service.impl;
2 |
3 | import com.ocean.dao.NewUserMapper;
4 | import com.ocean.dao.OldUserMapper;
5 | import com.ocean.model.NewUser;
6 | import com.ocean.model.OldUser;
7 | import com.ocean.service.UserService;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Service;
10 |
11 | /**
12 | * @author guodahai
13 | * @version 2018/4/12 下午4:55
14 | */
15 | @Service
16 | public class UserServiceImpl implements UserService {
17 |
18 | @Autowired
19 | private NewUserMapper newUserMapper;
20 |
21 | @Autowired
22 | private OldUserMapper oldUserMapper;
23 |
24 | @Override
25 | public NewUser queryNewUser(Integer id) {
26 | return newUserMapper.queryById(id);
27 | }
28 |
29 | @Override
30 | public OldUser queryOldUser(Integer id) {
31 | return oldUserMapper.queryById(id);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/mybatis/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8089
2 |
3 | old.db.driverClass=com.mysql.jdbc.Driver
4 | old.db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/old
5 | old.db.user=root
6 | old.db.password=root
7 |
8 | new.db.driverClass=com.mysql.jdbc.Driver
9 | new.db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/new
10 | new.db.user=root
11 | new.db.password=root
12 |
13 | spring.datasource.initialSize=2
14 | spring.datasource.minIdle=1
15 | spring.datasource.maxActive=5
16 | spring.datasource.maxWait=6000
17 | spring.datasource.timeBetweenEvictionRunsMillis=6000
18 | spring.datasource.minEvictableIdleTimeMillis=300000
19 | spring.datasource.validationQuery=select 'x'
20 | spring.datasource.testWhileIdle=true
21 | spring.datasource.testOnBorrow=true
22 | spring.datasource.testOnReturn=true
23 | spring.datasource.poolPreparedStatements=true
24 |
--------------------------------------------------------------------------------
/mybatis/src/test/java/com/ocean/MybatisApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ocean;
2 |
3 | import org.junit.Test;
4 |
5 | public class MybatisApplicationTests {
6 |
7 | @Test
8 | public void contextLoads() {
9 | }
10 |
11 | @Test
12 | public void test() {
13 | double high = 0.0001;
14 | int i = 0;
15 | while (high < 8848) {
16 | high *= 2;
17 | i++;
18 | }
19 | System.out.println(i);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/rabbitmq/README.md:
--------------------------------------------------------------------------------
1 | 1、direct模式
2 |
3 | 1.1 简单模式 hello
4 | 一个生产者,一个队列,一个消费者,使用默认Exchange
5 | 生产者:只需指定routingKey rabbitTemplate.convertAndSend(routingKey, object);
6 | 消费者:监听该队列 @RabbitListener(queues = "hello")
7 |
8 | 1.2 工作队列模式work
9 | 一个生产者,一个队列,多个消费者,共享任务,排队消费
10 | 功能:一个生产者,多个消费者,每个消费者获取到的消息唯一,多个消费者只有一个队列
11 | 任务队列:避免立即做一个资源密集型任务,必须等待它完成,而是把这个任务安排到稍后再做。
12 | 我们将任务封装为消息并将其发送给队列。后台运行的工作进程将弹出任务并最终执行作业。
13 | 当有多个worker同时运行时,任务将在它们之间共享。
14 | 生产者:只需指定routingKey; rabbitTemplate.convertAndSend(routingKey, object);
15 | 消费者:多个消费者监听同一队列 @RabbitListener(queues = "work")
16 |
17 | 1.3 路由模式 Routing
18 | 说明:生产者发送消息到交换机并且要指定路由key,消费者将队列绑定到交换机时需要指定路由key
19 |
20 | 2、fanout模式
21 |
22 | 2.1 发布/订阅模式 Publish/Subscribe
23 | 功能:一个生产者发送的消息会被多个消费者获取。一个生产者、一个交换机、多个队列、多个消费者
24 | 如果消息发送到没有队列绑定的交换机上,那么消息将丢失。
25 | 交换机不能存储消息,消息存储在队列中
26 | 生产者:可以将消息发送到队列或者是交换机。
27 | 消费者:只能从队列中获取消息。
28 |
29 | 3、topic模式
30 |
31 | 3.1 topic模式
32 | 队列绑定交换机,并指定队列routing key规则,更具规则来接受生产者发送的消息
33 | 说明:生产者P发送消息到交换机X,type=topic,交换机根据绑定队列的routing key的值进行通配符匹配;
34 | 符号#:匹配一个或者多个词 topic.# 可以匹配 topic.one或者topic.one.cor
35 | 符号*:只能匹配一个词 topic.* 可以匹配 topic.one或者topic.two
36 |
--------------------------------------------------------------------------------
/rabbitmq/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | com.ocean
8 | springboot
9 | 0.0.1-SNAPSHOT
10 |
11 |
12 | rabbitmq
13 | 0.0.1-SNAPSHOT
14 | jar
15 |
16 |
17 |
18 |
19 | com.ocean
20 | common
21 | 0.0.1-SNAPSHOT
22 |
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-amqp
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/config/DirectRabbitConfig.java:
--------------------------------------------------------------------------------
1 | package com.config;
2 |
3 | import org.springframework.amqp.core.Queue;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 |
8 | /**
9 | * Exchange四种模式之一:Direct
10 | * 无需绑定Exchange,需要指定RouteKey
11 | *
12 | * @author guodahai
13 | */
14 | @Configuration
15 | public class DirectRabbitConfig {
16 |
17 | /**
18 | * 简单模式 Hello Word
19 | * 一个生产者,一个队列,一个消费者
20 | *
21 | * @return
22 | */
23 | @Bean
24 | public Queue helloQueue() {
25 | return new Queue("hello");
26 | }
27 |
28 | /**
29 | * 工作队列模式Work Queue
30 | * 一个生产者,一个队列,多个消费者
31 | *
32 | * @return
33 | */
34 | @Bean
35 | public Queue workQueue() {
36 | return new Queue("work");
37 | }
38 |
39 | @Bean
40 | public Queue objectQueue() {
41 | return new Queue("object");
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/config/FanoutRabbitConfig.java:
--------------------------------------------------------------------------------
1 | package com.config;
2 |
3 | import org.springframework.amqp.core.Binding;
4 | import org.springframework.amqp.core.BindingBuilder;
5 | import org.springframework.amqp.core.FanoutExchange;
6 | import org.springframework.amqp.core.Queue;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 |
11 | /**
12 | * Exchange四种模式之一:Fanout
13 | * 提前绑定Exchange,不需要指定RouteKey
14 | * 一个生产者、一个交换机、多个队列、多个消费者
15 | *
16 | * @author guodahai
17 | * @version 2018/5/4 下午3:38
18 | */
19 | @Configuration
20 | public class FanoutRabbitConfig {
21 |
22 | @Bean
23 | public Queue AMessage() {
24 | return new Queue("fanout.A");
25 | }
26 |
27 | @Bean
28 | public Queue BMessage() {
29 | return new Queue("fanout.B");
30 | }
31 |
32 | @Bean
33 | public Queue CMessage() {
34 | return new Queue("fanout.C");
35 | }
36 |
37 | @Bean
38 | FanoutExchange fanoutExchange() {
39 | return new FanoutExchange("fanoutExchange");
40 | }
41 |
42 | @Bean
43 | Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
44 | return BindingBuilder.bind(AMessage).to(fanoutExchange);
45 | }
46 |
47 | @Bean
48 | Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
49 | return BindingBuilder.bind(BMessage).to(fanoutExchange);
50 | }
51 |
52 | @Bean
53 | Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
54 | return BindingBuilder.bind(CMessage).to(fanoutExchange);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/config/RouteRabbitConfig.java:
--------------------------------------------------------------------------------
1 | package com.config;
2 |
3 | import org.springframework.amqp.core.Binding;
4 | import org.springframework.amqp.core.BindingBuilder;
5 | import org.springframework.amqp.core.DirectExchange;
6 | import org.springframework.amqp.core.Queue;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | /**
11 | * 路由模式
12 | *
13 | * @author guodahai
14 | * @version 2018/5/18 下午4:51
15 | */
16 | @Configuration
17 | public class RouteRabbitConfig {
18 |
19 | @Bean
20 | public Queue routeA() {
21 | return new Queue("route.A");
22 | }
23 |
24 | @Bean
25 | public Queue routeB() {
26 | return new Queue("route.B");
27 | }
28 |
29 | @Bean
30 | DirectExchange directExchange() {
31 | return new DirectExchange("routing");
32 | }
33 |
34 | @Bean
35 | Binding bindingRouteA(Queue routeA, DirectExchange directExchange) {
36 | return BindingBuilder.bind(routeA).to(directExchange).with("info");
37 | }
38 |
39 | @Bean
40 | Binding bindingRouteB(Queue routeB, DirectExchange directExchange) {
41 | return BindingBuilder.bind(routeB).to(directExchange).with("error");
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/RabbitmqApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author guodahai
8 | */
9 | @SpringBootApplication
10 | public class RabbitmqApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(RabbitmqApplication.class, args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/controller/SendController.java:
--------------------------------------------------------------------------------
1 | package com.ocean.controller;
2 |
3 | import com.ocean.common.ControllerExecutor;
4 | import com.ocean.common.ResponseResult;
5 | import com.ocean.common.ServiceException;
6 | import com.ocean.model.Message;
7 | import com.ocean.service.SendService;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.web.bind.annotation.*;
10 |
11 | /**
12 | * @author guodahai
13 | * @version 2018/4/20 下午3:37
14 | */
15 | @RestController
16 | @RequestMapping("/send")
17 | public class SendController {
18 |
19 | @Autowired
20 | private SendService sendService;
21 |
22 | @PostMapping
23 | public ResponseResult sendHello(@RequestBody Message request) {
24 | return new ControllerExecutor(request) {
25 |
26 | @Override
27 | public void checkParam(Message... param) throws ServiceException {
28 |
29 | }
30 |
31 | @Override
32 | public Boolean executeService(Message... param) throws ServiceException {
33 | return sendService.send(request);
34 | }
35 | }.execute(request);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/fanout/FanoutReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.fanout;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
6 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * Fanout模式
11 | *
12 | * @author guodahai
13 | */
14 | @Component
15 | public class FanoutReceiver {
16 |
17 | private final Logger logger = LoggerFactory.getLogger(FanoutReceiver.class);
18 |
19 | /**
20 | * 方法级别Listener
21 | *
22 | * @param message
23 | */
24 | @RabbitHandler
25 | @RabbitListener(queues = "fanout.A")
26 | public void processA(String message) {
27 | logger.warn("fanout Receiver A: " + message);
28 | }
29 |
30 |
31 | @RabbitHandler
32 | @RabbitListener(queues = "fanout.B")
33 | public void processB(String message) {
34 | logger.warn("fanout Receiver B: " + message);
35 | }
36 |
37 |
38 | @RabbitHandler
39 | @RabbitListener(queues = "fanout.C")
40 | public void processC(String message) {
41 | logger.warn("fanout Receiver C: " + message);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/hello/HelloReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.hello;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
6 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * @author guodahai
11 | */
12 | @Component
13 | @RabbitListener(queues = "hello")
14 | public class HelloReceiver {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(HelloReceiver.class);
17 |
18 | @RabbitHandler
19 | public void process(String message) {
20 | logger.warn("Receiver : " + message);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/object/ObjectReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.object;
2 |
3 | import com.ocean.model.User;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
7 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
8 | import org.springframework.stereotype.Component;
9 |
10 | /**
11 | * @author guodahai
12 | */
13 | @Component
14 | @RabbitListener(queues = "object")
15 | public class ObjectReceiver {
16 |
17 | private final Logger logger = LoggerFactory.getLogger(ObjectReceiver.class);
18 |
19 | @RabbitHandler
20 | public void process(User user) {
21 | logger.warn("Receiver object : " + user);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/route/RouteReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.route;
2 |
3 | import com.ocean.listener.fanout.FanoutReceiver;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
7 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
8 | import org.springframework.stereotype.Component;
9 |
10 | /**
11 | * @author guodahai
12 | * @version 2018/5/18 下午5:04
13 | */
14 | @Component
15 | public class RouteReceiver {
16 |
17 | private final Logger logger = LoggerFactory.getLogger(FanoutReceiver.class);
18 |
19 | @RabbitHandler
20 | @RabbitListener(queues = "route.A")
21 | public void processA(String message) {
22 | logger.warn("route Receiver A: " + message);
23 | }
24 |
25 |
26 | @RabbitHandler
27 | @RabbitListener(queues = "route.B")
28 | public void processB(String message) {
29 | logger.warn("route Receiver B: " + message);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/topic/TopicReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.topic;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
6 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * @author guodahai
11 | */
12 | @Component
13 |
14 | public class TopicReceiver {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(TopicReceiver.class);
17 |
18 | @RabbitHandler
19 | @RabbitListener(queues = "message.one")
20 | public void processA(String message) {
21 | logger.warn("message.one receiver : " + message);
22 | }
23 |
24 | @RabbitHandler
25 | @RabbitListener(queues = "message.two")
26 | public void processB(String message) {
27 | logger.warn("message.two receiver : " + message);
28 | }
29 |
30 | @RabbitHandler
31 | @RabbitListener(queues = "info.one")
32 | public void processC(String message) {
33 | logger.warn("info.one receiver : " + message);
34 | }
35 |
36 | @RabbitHandler
37 | @RabbitListener(queues = "info.two")
38 | public void processD(String message) {
39 | logger.warn("info.two receiver : " + message);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/work/WorkReceiverOne.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.work;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
6 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * @author guodahai
11 | */
12 | @Component
13 | @RabbitListener(queues = "work")
14 | public class WorkReceiverOne {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(WorkReceiverOne.class);
17 |
18 | @RabbitHandler
19 | public void process(String message) {
20 | logger.warn("ReceiverOne: " + message);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/listener/work/WorkReceiverTwo.java:
--------------------------------------------------------------------------------
1 | package com.ocean.listener.work;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.amqp.rabbit.annotation.RabbitHandler;
6 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * @author guodahai
11 | */
12 | @Component
13 | @RabbitListener(queues = "work")
14 | public class WorkReceiverTwo {
15 |
16 | private final Logger logger = LoggerFactory.getLogger(WorkReceiverTwo.class);
17 |
18 | @RabbitHandler
19 | public void process(String message) {
20 | logger.warn("ReceiverTwo: " + message);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/model/Message.java:
--------------------------------------------------------------------------------
1 | package com.ocean.model;
2 |
3 | /**
4 | * @author guodahai
5 | * @version 2018/4/20 下午3:53
6 | */
7 | public class Message {
8 |
9 | /**
10 | * 交换机
11 | */
12 | private String exchange;
13 | /**
14 | * key
15 | */
16 | private String routeKey;
17 | /**
18 | * 消息内容
19 | */
20 | private Object msg;
21 |
22 | public String getExchange() {
23 | return exchange;
24 | }
25 |
26 | public void setExchange(String exchange) {
27 | this.exchange = exchange;
28 | }
29 |
30 | public String getRouteKey() {
31 | return routeKey;
32 | }
33 |
34 | public void setRouteKey(String routeKey) {
35 | this.routeKey = routeKey;
36 | }
37 |
38 | public Object getMsg() {
39 | return msg;
40 | }
41 |
42 | public void setMsg(Object msg) {
43 | this.msg = msg;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return "Message{" +
49 | "exchange='" + exchange + '\'' +
50 | ", routeKey='" + routeKey + '\'' +
51 | ", msg=" + msg +
52 | '}';
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/model/User.java:
--------------------------------------------------------------------------------
1 | package com.ocean.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @author guodahai
7 | */
8 | public class User implements Serializable {
9 |
10 | private String name;
11 |
12 | private String pass;
13 |
14 | public String getName() {
15 | return name;
16 | }
17 |
18 | public void setName(String name) {
19 | this.name = name;
20 | }
21 |
22 | public String getPass() {
23 | return pass;
24 | }
25 |
26 | public void setPass(String pass) {
27 | this.pass = pass;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "User{" +
33 | "name='" + name + '\'' +
34 | ", pass='" + pass + '\'' +
35 | '}';
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/service/SendService.java:
--------------------------------------------------------------------------------
1 | package com.ocean.service;
2 |
3 | import com.ocean.common.ServiceException;
4 | import com.ocean.model.Message;
5 |
6 | /**
7 | * @author guodahai
8 | * @version 2018/4/20 下午3:40
9 | */
10 | public interface SendService {
11 |
12 | /**
13 | * 消息发送
14 | *
15 | * @param request
16 | * @return
17 | */
18 | Boolean send(Message request) throws ServiceException;
19 |
20 | /**
21 | * 简单模式、工作队列模式
22 | *
23 | * @param routingKey
24 | * @param object
25 | */
26 | void send(String routingKey, Object object) throws ServiceException;
27 |
28 | /**
29 | * Exchange模式
30 | *
31 | * @param exchange
32 | * @param routingKey
33 | * @param object
34 | */
35 | void send(String exchange, String routingKey, Object object) throws ServiceException;
36 | }
37 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/java/com/ocean/service/impl/SendServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.ocean.service.impl;
2 |
3 | import com.ocean.common.ErrorCodeEnum;
4 | import com.ocean.common.ServiceException;
5 | import com.ocean.model.Message;
6 | import com.ocean.service.SendService;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.amqp.core.AmqpTemplate;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 |
13 | /**
14 | * @author guodahai
15 | * @version 2018/4/20 下午3:41
16 | */
17 | @Service
18 | public class SendServiceImpl implements SendService {
19 |
20 | private final Logger logger = LoggerFactory.getLogger(SendServiceImpl.class);
21 |
22 | @Autowired
23 | private AmqpTemplate rabbitTemplate;
24 |
25 | @Override
26 | public Boolean send(Message request) throws ServiceException {
27 | String exchange = request.getExchange();
28 | String routingKey = request.getRouteKey();
29 | Object object = request.getMsg();
30 | try {
31 | if (null == exchange) {
32 | send(routingKey, object);
33 | } else {
34 | send(exchange, routingKey, object);
35 | }
36 | } catch (ServiceException e) {
37 | logger.warn("发送消息失败!");
38 | throw new ServiceException(ErrorCodeEnum.P99);
39 | }
40 | return true;
41 | }
42 |
43 | @Override
44 | public void send(String routingKey, Object object) throws ServiceException {
45 | rabbitTemplate.convertAndSend(routingKey, object);
46 | }
47 |
48 | @Override
49 | public void send(String exchange, String routingKey, Object object) throws ServiceException {
50 | rabbitTemplate.convertAndSend(exchange, routingKey, object);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/rabbitmq/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=spring-boot-rabbitmq
2 | spring.rabbitmq.host=127.0.0.1
3 | spring.rabbitmq.port=5672
4 | spring.rabbitmq.username=guest
5 | spring.rabbitmq.password=guest
--------------------------------------------------------------------------------
/rabbitmq/src/test/java/com/ocean/RabbitmqApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ocean;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class RabbitmqApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/rocketmq/README.md:
--------------------------------------------------------------------------------
1 | docker run -d -p 9876:9876 -v /data/namesrv/logs:/root/logs -v /data/namesrv/store:/root/store --name rmqnamesrv rocketmqinc/rocketmq:4.4.0 sh mqnamesrv
2 | docker run -d -p 10911:10911 -p 10909:10909 -v /data/broker/logs:/root/logs -v /data/broker/store:/root/store --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" rocketmqinc/rocketmq:4.4.0 sh mqbroker
3 | docker run -e "JAVA_OPTS=-Drocketmq.namesrv.addr=127.0.0.1:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" -p 8088:8080 -d --name rmq-dashboard styletang/rocketmq-console-ng
4 |
5 | docker start rmqnamesrv rmqbroker
--------------------------------------------------------------------------------
/rocketmq/docker-compose-rocketmq.yml:
--------------------------------------------------------------------------------
1 | version: '3.5'
2 |
3 | services:
4 | rmqnamesrv:
5 | image: foxiswho/rocketmq:server-4.5.2
6 | container_name: rmqnamesrv
7 | ports:
8 | - 9876:9876
9 | volumes:
10 | - ./rmq/logs:/opt/logs
11 | - ./rmq/store:/opt/store
12 | environment:
13 | JAVA_OPT_EXT: "-Duser.home=/opt -Xms128m -Xmx128m -Xmn128m"
14 | networks:
15 | rmq:
16 | aliases:
17 | - rmqnamesrv
18 | rmqbroker:
19 | image: foxiswho/rocketmq:broker-4.5.2
20 | container_name: rmqbroker
21 | ports:
22 | - 10909:10909
23 | - 10911:10911
24 | volumes:
25 | - ./rmq/logs:/opt/logs
26 | - ./rmq/store:/opt/store
27 | - ./rmq/brokerconf/broker.conf:/etc/rocketmq/broker.conf
28 | environment:
29 | JAVA_OPT_EXT: "-Duser.home=/opt -server -Xms128m -Xmx128m -Xmn128m"
30 | command: ["/bin/bash","mqbroker","-c","/etc/rocketmq/broker.conf","-n","rmqnamesrv:9876","autoCreateTopicEnable=true"]
31 | depends_on:
32 | - rmqnamesrv
33 | networks:
34 | rmq:
35 | aliases:
36 | - rmqbroker
37 |
38 | rmqconsole:
39 | image: styletang/rocketmq-console-ng
40 | container_name: rmqconsole
41 | ports:
42 | - 8180:8080
43 | environment:
44 | JAVA_OPTS: "-Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
45 | depends_on:
46 | - rmqnamesrv
47 | networks:
48 | rmq:
49 | aliases:
50 | - rmqconsole
51 |
52 | networks:
53 | rmq:
54 | name: rmq
55 | driver: bridge
--------------------------------------------------------------------------------
/rocketmq/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | com.ocean
8 | springboot
9 | 0.0.1-SNAPSHOT
10 |
11 |
12 | rocketmq
13 | 1.0-SNAPSHOT
14 |
15 |
16 | rocket-producer
17 | rocket-common
18 | rocket-consumer
19 |
20 | pom
21 |
22 |
23 |
24 | org.apache.rocketmq
25 | rocketmq-client
26 |
27 |
28 | org.projectlombok
29 | lombok
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/rocketmq/rmq/readme.md:
--------------------------------------------------------------------------------
1 | docker-compose
2 |
3 | 进入 本目录下,执行如下命令
4 | ```bash
5 | docker-compose up
6 | ```
7 |
8 | ```bash
9 | docker start rmqnamesrv
10 | docker start rmqbroker
11 | docker start rmqconsole
12 | ```
--------------------------------------------------------------------------------
/rocketmq/rocket-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | com.ocean
7 | rocketmq
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | rocket-common
13 |
14 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/annotation/EnableRocketMQConfig.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * RocketMQ启用注解
7 | *
8 | * @author ocean
9 | */
10 | @Target(ElementType.TYPE)
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Documented
13 | @Inherited
14 | public @interface EnableRocketMQConfig {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/annotation/RocketMQConsumer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.annotation;
2 |
3 | import com.ocean.rocket.enums.ConsumeMode;
4 | import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
5 | import org.springframework.stereotype.Component;
6 |
7 | import java.lang.annotation.*;
8 |
9 | /**
10 | * RocketMQ消费者自动装配注解
11 | *
12 | * @author ocean
13 | */
14 | @Target(ElementType.TYPE)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | @Documented
17 | @Component
18 | public @interface RocketMQConsumer {
19 | /**
20 | * 消费group名称
21 | */
22 | String consumerGroup();
23 |
24 | /**
25 | * 消息topic
26 | */
27 | String topic();
28 |
29 | /**
30 | * 消息标签,用于区分一类消息
31 | */
32 | String[] tag() default {"*"};
33 |
34 | /**
35 | * 广播模式消费: BROADCASTING
36 | * 集群模式消费(默认): CLUSTERING
37 | */
38 | MessageModel messageMode() default MessageModel.CLUSTERING;
39 |
40 | /**
41 | * 并发消费(默认): CONCURRENTLY
42 | * 顺序消费: ORDERLY
43 | */
44 | ConsumeMode consumeMode() default ConsumeMode.CONCURRENTLY;
45 | }
46 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/annotation/RocketMQKey.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.annotation;
2 |
3 | import java.lang.annotation.*;
4 |
5 | /**
6 | * 用来标识作为消息key的字段,尽可能全局唯一
7 | * prefix 会作为前缀拼到字段值前面
8 | *
9 | * @author ocean
10 | */
11 | @Target(ElementType.FIELD)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Documented
14 | public @interface RocketMQKey {
15 | String prefix() default "";
16 | }
17 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/annotation/RocketMQProducer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.annotation;
2 |
3 | import org.springframework.stereotype.Component;
4 |
5 | import java.lang.annotation.*;
6 |
7 | /**
8 | * RocketMQ生产者自动装配注解
9 | *
10 | * @author ocean
11 | */
12 | @Target(ElementType.TYPE)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Documented
15 | @Component
16 | public @interface RocketMQProducer {
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/base/AbstractRocketMQConsumer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.base;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.apache.rocketmq.common.message.MessageExt;
6 | import org.springframework.util.Assert;
7 |
8 | import java.lang.reflect.ParameterizedType;
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * RocketMQ消费者基类
13 | *
14 | * @author ocean
15 | */
16 | @Slf4j
17 | public abstract class AbstractRocketMQConsumer {
18 |
19 | /**
20 | * 反序列化解析消息
21 | *
22 | * @param message 消息体
23 | * @return 序列化结果
24 | */
25 | protected T parseMessage(MessageExt message) {
26 | if (message == null || message.getBody() == null) {
27 | return null;
28 | }
29 | final Type type = this.getMessageType();
30 | if (type instanceof Class) {
31 | if (type.getTypeName().equals(String.class.getName())) {
32 | return (T) new String(message.getBody());
33 | }
34 | try {
35 | T data = JSON.parseObject(new String(message.getBody()), type);
36 | return data;
37 | } catch (Exception e) {
38 | log.warn("Parse message json fail:{}", new String(message.getBody()), e);
39 | }
40 | } else {
41 | log.warn("Parse msg fail: {}", message);
42 | }
43 | return null;
44 | }
45 |
46 | /**
47 | * 解析消息类型
48 | *
49 | * @return 消息类型
50 | */
51 | protected Type getMessageType() {
52 | Type superType = this.getClass().getGenericSuperclass();
53 | if (superType instanceof ParameterizedType) {
54 | ParameterizedType parameterizedType = (ParameterizedType) superType;
55 | Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
56 | Assert.isTrue(actualTypeArguments.length == 1, "Number of type arguments must be 1");
57 | return actualTypeArguments[0];
58 | } else {
59 | // 如果没有定义泛型,解析为Object
60 | return Object.class;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/config/BaseAutoConfig.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.config;
2 |
3 | import com.ocean.rocket.annotation.EnableRocketMQConfig;
4 | import com.ocean.rocket.base.AbstractMQPushConsumer;
5 | import com.ocean.rocket.constants.MessageConstant;
6 | import org.springframework.beans.BeansException;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
9 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.ApplicationContextAware;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.core.env.StandardEnvironment;
14 |
15 | import javax.annotation.PostConstruct;
16 |
17 | /**
18 | * RocketMQ基本配置
19 | *
20 | * @author ocean
21 | */
22 | @Configuration
23 | @ConditionalOnBean(annotation = EnableRocketMQConfig.class)
24 | @AutoConfigureAfter(AbstractMQPushConsumer.class)
25 | public class BaseAutoConfig implements ApplicationContextAware {
26 | @Autowired
27 | protected StandardEnvironment standardEnvironment;
28 |
29 | ApplicationContext applicationContext;
30 |
31 | @Override
32 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
33 | this.applicationContext = applicationContext;
34 | }
35 |
36 | @PostConstruct
37 | public void setClientLoggerProperties() {
38 | setSystemProperty(MessageConstant.ROCKETMQ_CLIENT_LOG_LOADCONFIG);
39 | setSystemProperty(MessageConstant.ROCKETMQ_CLIENT_LOGROOT);
40 | setSystemProperty(MessageConstant.CLIENT_LOG_LEVEL);
41 | }
42 |
43 | private void setSystemProperty(String key) {
44 | if (standardEnvironment.containsProperty(key)) {
45 | System.setProperty(key, standardEnvironment.getProperty(key));
46 | }
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/config/ConsumerProperties.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.config;
2 |
3 | import lombok.Data;
4 | import org.apache.rocketmq.client.ClientConfig;
5 | import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
6 | import org.springframework.boot.context.properties.ConfigurationProperties;
7 |
8 | /**
9 | * RocketMQ的consumer配置参数
10 | *
11 | * @author ocean
12 | */
13 | @Data
14 | @ConfigurationProperties(prefix = ConsumerProperties.PREFIX)
15 | public class ConsumerProperties extends ClientConfig {
16 | public static final String PREFIX = "rocket.consumer";
17 |
18 | private String namesrvAddr;
19 | /**
20 | * 是否开启VIP通道
21 | */
22 | private boolean vipChannelEnabled = false;
23 |
24 | /**
25 | * Max re-consume times. -1 means 16 times.
26 | * If messages are re-consumed more than {@link #maxReconsumeTimes} before success, it's be directed to a deletion
27 | * queue waiting.
28 | */
29 | private int maxReconsumeTimes = -1;
30 |
31 | /**
32 | * Maximum number of retry to perform internally before claiming consume failure.
33 | */
34 | private int retryTimesWhenConsumeFailed = 16;
35 |
36 | /**
37 | * Maximum amount of time in minutes a message may block the consuming thread.
38 | */
39 | private long consumeTimeout = 15;
40 |
41 | /**
42 | * Consuming point on consumer booting.
43 | */
44 | private String consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET.toString();
45 | }
46 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/config/ProducerProperties.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.config;
2 |
3 | import lombok.Data;
4 | import org.apache.rocketmq.client.ClientConfig;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 |
7 | /**
8 | * RocketMQ的producer配置参数
9 | *
10 | * @author ocean
11 | */
12 | @Data
13 | @ConfigurationProperties(prefix = ProducerProperties.PREFIX)
14 | public class ProducerProperties extends ClientConfig {
15 | public static final String PREFIX = "rocket.producer";
16 | /**
17 | * namesrv地址
18 | */
19 | private String namesrvAddr;
20 | /**
21 | * 生产者Group名称
22 | */
23 | private String producerGroup;
24 | /**
25 | * 是否开启VIP通道
26 | */
27 | private boolean vipChannelEnabled = false;
28 |
29 | /**
30 | * Number of queues to create per default topic.
31 | */
32 | private volatile int defaultTopicQueueNums = 4;
33 |
34 | /**
35 | * Timeout for sending messages.
36 | */
37 | private int sendMsgTimeout = 3000;
38 |
39 | /**
40 | * Maximum number of retry to perform internally before claiming sending
41 | * failure in synchronous mode.
42 | * This may potentially cause message duplication which is up to application
43 | * developers to resolve.
44 | */
45 | private int retryTimesWhenSendFailed = 3;
46 |
47 | /**
48 | * Maximum number of retry to perform internally before claiming sending
49 | * failure in asynchronous mode.
50 | *
51 | *
52 | * This may potentially cause message duplication which is up to application
53 | * developers to resolve.
54 | */
55 | private int retryTimesWhenSendAsyncFailed = 3;
56 |
57 | /**
58 | * Indicate whether to retry another broker on sending failure internally.
59 | */
60 | private boolean retryAnotherBrokerWhenNotStoreOK = false;
61 |
62 | /**
63 | * Maximum allowed message size in bytes.
64 | * 4M
65 | */
66 | private int maxMessageSize = 1024 * 1024 * 4;
67 |
68 | /**
69 | * 是否启用事务
70 | */
71 | private boolean transaction = false;
72 | }
73 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/constants/MessageConstant.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.constants;
2 |
3 | /**
4 | * 消息常量
5 | *
6 | * @author 003238
7 | */
8 | public class MessageConstant {
9 | /**
10 | * 默认字符编码
11 | */
12 | public final static String DEFAULT_CHARSET = "UTF-8";
13 |
14 | /**
15 | * rocketmq是否加载客户端日志
16 | */
17 | public final static String ROCKETMQ_CLIENT_LOG_LOADCONFIG = "rocketmq.client.log.loadconfig";
18 |
19 | /**
20 | * rocketmq日志路径
21 | */
22 | public final static String ROCKETMQ_CLIENT_LOGROOT = "rocket.client.logRoot";
23 |
24 | /**
25 | * rocketmq日志级别
26 | */
27 | public static final String CLIENT_LOG_LEVEL = "rocket.client.logLevel";
28 |
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/enums/ConsumeMode.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.enums;
2 |
3 | /**
4 | * 消费类型
5 | *
6 | * @author 003238
7 | */
8 | public enum ConsumeMode {
9 | /**
10 | * consume delivered messages concurrently
11 | */
12 | CONCURRENTLY,
13 |
14 | /**
15 | * consume delivered messages orderly, one queue, one thread
16 | */
17 | ORDERLY
18 | }
19 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/enums/DelayTimeLevel.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.enums;
2 |
3 | /**
4 | * 延长消息时间段枚举
5 | *
6 | * @author ocean
7 | */
8 | public enum DelayTimeLevel {
9 | /**
10 | * 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
11 | */
12 | SECOND_1(1),
13 | SECOND_5(2),
14 | SECOND_10(3),
15 | SECOND_30(4),
16 | MINUTE_1(5),
17 | MINUTE_2(6),
18 | MINUTE_3(7),
19 | MINUTE_4(8),
20 | MINUTE_5(9),
21 | MINUTE_6(10),
22 | MINUTE_7(11),
23 | MINUTE_8(12),
24 | MINUTE_9(13),
25 | MINUTE_10(14),
26 | MINUTE_20(15),
27 | MINUTE_30(16),
28 | HOUR_1(17),
29 | HOUR_2(18);
30 |
31 | private int level;
32 |
33 | DelayTimeLevel(int level) {
34 | this.level = level;
35 | }
36 |
37 | public int getLevel() {
38 | return level;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/exception/RocketMqException.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.exception;
2 |
3 | /**
4 | * RocketMQ自定义异常
5 | *
6 | * @author 003238
7 | */
8 | public class RocketMqException extends RuntimeException {
9 |
10 | private static final long serialVersionUID = -3878975849119141383L;
11 |
12 | public RocketMqException(String msg) {
13 | super(msg);
14 | }
15 |
16 | public RocketMqException(String msg, Throwable cause) {
17 | super(msg, cause);
18 | }
19 |
20 | public RocketMqException(Throwable cause) {
21 | super(cause);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/hook/ConsumeOneMessageAdvice.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.hook;
2 |
3 | import org.apache.rocketmq.common.message.MessageExt;
4 |
5 | /**
6 | * @author 003238
7 | */
8 | public interface ConsumeOneMessageAdvice {
9 | String hookName();
10 |
11 | void consumeMessageBefore(final MessageExt msg);
12 |
13 | void consumeMessageAfter(final MessageExt msg);
14 | }
15 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/hook/ProducerShutdownHook.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.hook;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.apache.rocketmq.client.producer.MQProducer;
5 |
6 | /**
7 | * MQProducer关闭hook
8 | *
9 | * @author 003238
10 | */
11 | @Slf4j
12 | public class ProducerShutdownHook extends Thread {
13 |
14 | private MQProducer producer;
15 |
16 | public ProducerShutdownHook(MQProducer producer) {
17 | this.producer = producer;
18 | }
19 |
20 | @Override
21 | public void run() {
22 | if (producer != null) {
23 | log.info("MQProducer shutdownHook");
24 | producer.shutdown();
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/src/main/java/com/ocean/rocket/hook/PushConsumerShutdownHook.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.hook;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
5 |
6 | /**
7 | * DefaultMQPushConsumer关闭hook
8 | *
9 | * @author 003238
10 | */
11 | @Slf4j
12 | public class PushConsumerShutdownHook extends Thread {
13 |
14 | private DefaultMQPushConsumer consumer;
15 |
16 | public PushConsumerShutdownHook(DefaultMQPushConsumer consumer) {
17 | this.consumer = consumer;
18 | }
19 |
20 | @Override
21 | public void run() {
22 | if (consumer != null) {
23 | log.info("DefaultMQPushConsumer shutdownHook:{}", consumer.getConsumerGroup());
24 | consumer.shutdown();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/target/maven-archiver/pom.properties:
--------------------------------------------------------------------------------
1 | #Generated by Apache Maven
2 | #Wed Sep 18 19:09:18 CST 2019
3 | version=1.0-SNAPSHOT
4 | groupId=com.ocean
5 | artifactId=rocket-common
6 |
--------------------------------------------------------------------------------
/rocketmq/rocket-common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/rocketmq/rocket-common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
--------------------------------------------------------------------------------
/rocketmq/rocket-common/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/rocketmq/rocket-common/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
--------------------------------------------------------------------------------
/rocketmq/rocket-common/target/rocket-comon-1.0-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/rocketmq/rocket-common/target/rocket-comon-1.0-SNAPSHOT.jar
--------------------------------------------------------------------------------
/rocketmq/rocket-consumer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | rocketmq
7 | com.ocean
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | rocket-consumer
13 |
14 |
15 |
16 | com.ocean
17 | rocket-common
18 | 1.0-SNAPSHOT
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/rocketmq/rocket-consumer/src/main/java/com/ocean/rocket/RocketMqConsumerApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket;
2 |
3 | import com.ocean.rocket.annotation.EnableRocketMQConfig;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | /**
8 | * @author guodahai
9 | */
10 | @EnableRocketMQConfig
11 | @SpringBootApplication
12 | public class RocketMqConsumerApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(RocketMqConsumerApplication.class, args);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/rocketmq/rocket-consumer/src/main/java/com/ocean/rocket/consumer/Consumer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.consumer;
2 |
3 | import com.ocean.rocket.annotation.RocketMQConsumer;
4 | import com.ocean.rocket.base.AbstractMQPushConsumer;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.apache.rocketmq.common.message.MessageExt;
7 |
8 | /**
9 | * 生产者
10 | *
11 | * @author ocean
12 | */
13 | @Slf4j
14 | @RocketMQConsumer(consumerGroup = "ocean", topic = "topic")
15 | public class Consumer extends AbstractMQPushConsumer {
16 |
17 | @Override
18 | public boolean processMessage(String message, MessageExt messageExt) {
19 | log.warn("Consumer========");
20 | return true;
21 | }
22 | }
--------------------------------------------------------------------------------
/rocketmq/rocket-consumer/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | rocket.producer.namesrvAddr=127.0.0.1:9876
2 | rocket.producer.producerGroup=ocean
3 | rocket.producer.vipChannelEnabled=false
4 | rocket.consumer.namesrvAddr=127.0.0.1:9876
5 | rocket.consumer.vipChannelEnabled=false
6 | rocket.client.log.loadconfig=false
7 | server.port=8082
8 |
--------------------------------------------------------------------------------
/rocketmq/rocket-producer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.ocean
8 | rocketmq
9 | 1.0-SNAPSHOT
10 |
11 |
12 | rocket-producer
13 |
14 |
15 |
16 | com.ocean
17 | rocket-common
18 | 1.0-SNAPSHOT
19 |
20 |
21 |
--------------------------------------------------------------------------------
/rocketmq/rocket-producer/src/main/java/com/ocean/rocket/RocketMqProducerApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket;
2 |
3 | import com.ocean.rocket.annotation.EnableRocketMQConfig;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | /**
8 | * @author guodahai
9 | */
10 | @EnableRocketMQConfig
11 | @SpringBootApplication
12 | public class RocketMqProducerApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(RocketMqProducerApplication.class, args);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/rocketmq/rocket-producer/src/main/java/com/ocean/rocket/producer/Producer.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.producer;
2 |
3 | import com.ocean.rocket.annotation.RocketMQProducer;
4 | import com.ocean.rocket.base.AbstractRocketMQProducer;
5 | import org.apache.rocketmq.client.producer.SendResult;
6 | import org.springframework.stereotype.Component;
7 |
8 | /**
9 | * 生产者
10 | *
11 | * @author ocean
12 | */
13 | @Component
14 | @RocketMQProducer
15 | public class Producer extends AbstractRocketMQProducer {
16 |
17 | /**
18 | * 重写此方法处理发送后的逻辑
19 | *
20 | * @param sendResult 发送结果
21 | */
22 | @Override
23 | public void doAfterSyncSend(SendResult sendResult) {
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/rocketmq/rocket-producer/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | rocket.producer.namesrvAddr=127.0.0.1:9876
2 | rocket.producer.producerGroup=ocean
3 | rocket.producer.vipChannelEnabled=false
4 | rocket.consumer.namesrvAddr=127.0.0.1:9876
5 | rocket.consumer.vipChannelEnabled=false
6 | rocket.client.log.loadconfig=false
7 | server.port=8081
--------------------------------------------------------------------------------
/rocketmq/rocket-producer/src/test/java/com/ocean/rocket/producer/ProducerTest.java:
--------------------------------------------------------------------------------
1 | package com.ocean.rocket.producer;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.ocean.rocket.RocketMqProducerApplication;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.apache.commons.lang3.StringUtils;
7 | import org.apache.rocketmq.client.exception.MQClientException;
8 | import org.apache.rocketmq.client.producer.LocalTransactionState;
9 | import org.apache.rocketmq.client.producer.SendResult;
10 | import org.apache.rocketmq.client.producer.TransactionListener;
11 | import org.apache.rocketmq.common.message.Message;
12 | import org.apache.rocketmq.common.message.MessageExt;
13 | import org.junit.Test;
14 | import org.junit.runner.RunWith;
15 | import org.springframework.boot.test.context.SpringBootTest;
16 | import org.springframework.test.context.junit4.SpringRunner;
17 |
18 | import javax.annotation.Resource;
19 |
20 | @Slf4j
21 | @RunWith(SpringRunner.class)
22 | @SpringBootTest(classes = RocketMqProducerApplication.class)
23 | public class ProducerTest {
24 |
25 | @Resource
26 | private Producer producer;
27 |
28 | /**
29 | * 发送同步消息
30 | */
31 | @Test
32 | public void test() {
33 | SendResult sendResult = producer.syncSend("topic", null, "message");
34 | log.info(JSON.toJSONString(sendResult));
35 | }
36 |
37 | /**
38 | * 发送事务消息
39 | *
40 | * @throws MQClientException
41 | */
42 | @Test
43 | public void sendMessageInTransaction() throws MQClientException {
44 | String str = "";
45 | producer.sendMessageInTransaction("topic", null, "message", str, new TransactionListener() {
46 |
47 | @Override
48 | public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
49 | //TODO 执行本地事务
50 | if (StringUtils.isEmpty(str)) {
51 | return LocalTransactionState.ROLLBACK_MESSAGE;
52 | }
53 | return LocalTransactionState.COMMIT_MESSAGE;
54 | }
55 |
56 | @Override
57 | public LocalTransactionState checkLocalTransaction(MessageExt msg) {
58 | //TODO 检查本地事务
59 | return LocalTransactionState.COMMIT_MESSAGE;
60 | }
61 | });
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/solr/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | solr
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | solr
11 | Demo project for Spring Boot
12 |
13 |
14 | com.ocean
15 | springboot
16 | 0.0.1-SNAPSHOT
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-data-solr
23 |
24 |
25 | org.apache.solr
26 | solr-solrj
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/SolrApplication.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class SolrApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(SolrApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/config/SolrConfig.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr.config;
2 |
3 | import org.apache.solr.client.solrj.SolrServer;
4 | import org.apache.solr.client.solrj.impl.HttpSolrServer;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | public class SolrConfig {
11 |
12 | @Value("${spring.data.solr.host}")
13 | private String URL;
14 |
15 | @Bean
16 | public SolrServer solrServer() {
17 | HttpSolrServer solrServer = new HttpSolrServer(URL);
18 | return solrServer;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/controller/ProductController.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr.controller;
2 |
3 | import com.ocean.solr.pojo.ResultModel;
4 | import com.ocean.solr.service.ProductService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 |
10 | /**
11 | * 商品搜索controller
12 | * Title: ProductController
13 | * Description:
14 | * Company: www.itcast.cn
15 | *
16 | * @version 1.0
17 | */
18 | @Controller
19 | public class ProductController {
20 |
21 | @Autowired
22 | private ProductService productService;
23 |
24 | @RequestMapping("/list")
25 | public String productSearch(String queryString, String catalog_name, String price,
26 | String sort, Integer page, Model model) throws Exception {
27 | //调用服务查询商品列表
28 | ResultModel resultModel = productService.queryProduct(queryString, catalog_name, price, sort, page);
29 | //传递给页面
30 | model.addAttribute("queryString", queryString);
31 | model.addAttribute("catalog_name", catalog_name);
32 | model.addAttribute("price", price);
33 | model.addAttribute("sort", sort);
34 | model.addAttribute("page", page);
35 | model.addAttribute("result", resultModel);
36 | //返回逻辑视图
37 | return "product_list";
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/dao/ProductDao.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr.dao;
2 |
3 | import com.ocean.solr.pojo.ProductModel;
4 | import com.ocean.solr.pojo.ResultModel;
5 | import org.apache.solr.client.solrj.SolrQuery;
6 | import org.apache.solr.client.solrj.SolrServer;
7 | import org.apache.solr.client.solrj.response.QueryResponse;
8 | import org.apache.solr.common.SolrDocument;
9 | import org.apache.solr.common.SolrDocumentList;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Repository;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 |
18 | /**
19 | * 商品搜索dao
20 | * Title: ProductDao
21 | * Description:
22 | * Company: www.itcast.cn
23 | * @version 1.0
24 | */
25 | @Repository
26 | public class ProductDao {
27 |
28 | @Autowired
29 | private SolrServer solrServer;
30 |
31 | public ResultModel search(SolrQuery query) throws Exception {
32 | //执行查询
33 | QueryResponse response = solrServer.query(query);
34 | //取查询结果
35 | SolrDocumentList solrDocumentList = response.getResults();
36 | //取查询结果总记录数
37 | ResultModel resultModel = new ResultModel();
38 | resultModel.setRecordCount(solrDocumentList.getNumFound());
39 | //商品列表
40 | List productList = new ArrayList<>();
41 | //取结果集
42 | for (SolrDocument solrDocument : solrDocumentList) {
43 | //创建一个商品对象
44 | ProductModel productModel = new ProductModel();
45 | productModel.setPid((String) solrDocument.get("id"));
46 | productModel.setCatalog_name((String) solrDocument.get("product_catalog_name"));
47 | //取高亮显示
48 | Map>> highlighting = response.getHighlighting();
49 | List list = highlighting.get(solrDocument.get("id")).get("product_name");
50 | String productName = "";
51 | if (list != null && list.size() > 0) {
52 | productName = list.get(0);
53 | } else {
54 | productName = (String) solrDocument.get("product_name");
55 | }
56 | productModel.setName(productName);
57 | productModel.setPicture((String) solrDocument.get("product_picture"));
58 | productModel.setPrice((float) solrDocument.get("product_price"));
59 | //添加到商品列表
60 | productList.add(productModel);
61 | }
62 | //添加到返回结果
63 | resultModel.setProductList(productList);
64 | return resultModel;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/pojo/ProductModel.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr.pojo;
2 |
3 | public class ProductModel {
4 | // 商品编号
5 | private String pid;
6 | // 商品名称
7 | private String name;
8 | // 商品分类名称
9 | private String catalog_name;
10 | // 价格
11 | private float price;
12 | // 商品描述
13 | private String description;
14 | // 图片名称
15 | private String picture;
16 |
17 | public String getPid() {
18 | return pid;
19 | }
20 |
21 | public void setPid(String pid) {
22 | this.pid = pid;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | public String getCatalog_name() {
34 | return catalog_name;
35 | }
36 |
37 | public void setCatalog_name(String catalog_name) {
38 | this.catalog_name = catalog_name;
39 | }
40 |
41 | public float getPrice() {
42 | return price;
43 | }
44 |
45 | public void setPrice(float price) {
46 | this.price = price;
47 | }
48 |
49 | public String getDescription() {
50 | return description;
51 | }
52 |
53 | public void setDescription(String description) {
54 | this.description = description;
55 | }
56 |
57 | public String getPicture() {
58 | return picture;
59 | }
60 |
61 | public void setPicture(String picture) {
62 | this.picture = picture;
63 | }
64 |
65 | }
--------------------------------------------------------------------------------
/solr/src/main/java/com/ocean/solr/pojo/ResultModel.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr.pojo;
2 |
3 | import java.util.List;
4 |
5 | public class ResultModel {
6 | // 商品列表
7 | private List productList;
8 | // 商品总数
9 | private Long recordCount;
10 | // 总页数
11 | private int pageCount;
12 | // 当前页
13 | private int curPage;
14 |
15 | public List getProductList() {
16 | return productList;
17 | }
18 |
19 | public void setProductList(List productList) {
20 | this.productList = productList;
21 | }
22 |
23 | public Long getRecordCount() {
24 | return recordCount;
25 | }
26 |
27 | public void setRecordCount(Long recordCount) {
28 | this.recordCount = recordCount;
29 | }
30 |
31 | public int getPageCount() {
32 | return pageCount;
33 | }
34 |
35 | public void setPageCount(int pageCount) {
36 | this.pageCount = pageCount;
37 | }
38 |
39 | public int getCurPage() {
40 | return curPage;
41 | }
42 |
43 | public void setCurPage(int curPage) {
44 | this.curPage = curPage;
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/solr/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8111
3 |
4 | spring:
5 | mvc:
6 | view:
7 | prefix: /WEB-INF/pages/
8 | suffix: .jsp
9 |
10 | spring.data.solr.host: http://127.0.0.1:8080/solr
--------------------------------------------------------------------------------
/solr/src/test/java/com/ocean/solr/SolrApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.ocean.solr;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class SolrApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/xxl-job/doc/XXL-JOB架构图.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/XXL-JOB架构图.pptx
--------------------------------------------------------------------------------
/xxl-job/doc/images/cnblog-首页-每日一博-第一.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/cnblog-首页-每日一博-第一.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/cnblog-首页-热门动弹-第一.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/cnblog-首页-热门动弹-第一.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/donate-alipay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/donate-alipay.jpg
--------------------------------------------------------------------------------
/xxl-job/doc/images/donate-paypal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/donate-paypal.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/donate-wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/donate-wechat.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/gitee-gvp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/gitee-gvp.jpg
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_6yC0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_6yC0.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_BPLG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_BPLG.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_EB65.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_EB65.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Fgql.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Fgql.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Hr2T.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Hr2T.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Qohm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Qohm.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_UDSo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_UDSo.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_V3vF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_V3vF.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Wb2o.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Wb2o.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Ypik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Ypik.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_Z9Qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_Z9Qr.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_ZAhX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_ZAhX.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_ZAsz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_ZAsz.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_dNUJ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_dNUJ.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_eYrv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_eYrv.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_hIci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_hIci.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_iUw0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_iUw0.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_inc8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_inc8.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_jOAU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_jOAU.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_jrdI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_jrdI.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_o8HQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_o8HQ.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_oLlM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_oLlM.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_tJOq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_tJOq.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/img_tvGI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/img_tvGI.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/qq群-一个xxl同学进了58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/qq群-一个xxl同学进了58.png
--------------------------------------------------------------------------------
/xxl-job/doc/images/xxl-logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/xxl-logo.jpg
--------------------------------------------------------------------------------
/xxl-job/doc/images/xxl-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdh7732/spring-boot/5430767dafee84e6f0b68e7bc5873cb43d92562d/xxl-job/doc/images/xxl-logo.png
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:7-jre-slim
2 | MAINTAINER xuxueli
3 |
4 | ENV PARAMS=""
5 |
6 | ENV TZ=PRC
7 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
8 |
9 | ADD target/xxl-job-admin-*.jar /app.jar
10 |
11 | ENTRYPOINT ["sh","-c","java -jar /app.jar $PARAMS"]
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author xuxueli 2018-10-28 00:38:13
8 | */
9 | @SpringBootApplication
10 | public class XxlJobAdminApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(XxlJobAdminApplication.class, args);
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobApiController.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.controller;
2 |
3 | import com.xxl.job.admin.controller.annotation.PermessionLimit;
4 | import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
5 | import com.xxl.job.core.biz.AdminBiz;
6 | import org.springframework.beans.factory.InitializingBean;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 |
10 | import javax.servlet.ServletException;
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 | import java.io.IOException;
14 |
15 | /**
16 | * Created by xuxueli on 17/5/10.
17 | */
18 | @Controller
19 | public class JobApiController implements InitializingBean {
20 |
21 |
22 | @Override
23 | public void afterPropertiesSet() throws Exception {
24 |
25 | }
26 |
27 | @RequestMapping(AdminBiz.MAPPING)
28 | @PermessionLimit(limit=false)
29 | public void api(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
30 | XxlJobDynamicScheduler.invokeAdminService(request, response);
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/annotation/PermessionLimit.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.controller.annotation;
2 |
3 |
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * 权限限制
11 | * @author xuxueli 2015-12-12 18:29:02
12 | */
13 | @Target(ElementType.METHOD)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface PermessionLimit {
16 |
17 | /**
18 | * 登录拦截 (默认拦截)
19 | */
20 | boolean limit() default true;
21 |
22 | }
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/CookieInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.controller.interceptor;
2 |
3 | import com.xxl.job.admin.core.util.FtlUtil;
4 | import com.xxl.job.admin.core.util.I18nUtil;
5 | import org.springframework.stereotype.Component;
6 | import org.springframework.web.servlet.ModelAndView;
7 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
8 |
9 | import javax.servlet.http.Cookie;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.util.HashMap;
13 |
14 | /**
15 | * push cookies to model as cookieMap
16 | *
17 | * @author xuxueli 2015-12-12 18:09:04
18 | */
19 | @Component
20 | public class CookieInterceptor extends HandlerInterceptorAdapter {
21 |
22 | @Override
23 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
24 | ModelAndView modelAndView) throws Exception {
25 |
26 | // cookie
27 | if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) {
28 | HashMap cookieMap = new HashMap();
29 | for (Cookie ck : request.getCookies()) {
30 | cookieMap.put(ck.getName(), ck);
31 | }
32 | modelAndView.addObject("cookieMap", cookieMap);
33 | }
34 |
35 | // static method
36 | if (modelAndView != null) {
37 | modelAndView.addObject("I18nUtil", FtlUtil.generateStaticModel(I18nUtil.class.getName()));
38 | }
39 |
40 | super.postHandle(request, response, handler, modelAndView);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.controller.interceptor;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
6 |
7 | import javax.annotation.Resource;
8 |
9 | /**
10 | * web mvc config
11 | *
12 | * @author xuxueli 2018-04-02 20:48:20
13 | */
14 | @Configuration
15 | public class WebMvcConfig extends WebMvcConfigurerAdapter {
16 |
17 | @Resource
18 | private PermissionInterceptor permissionInterceptor;
19 | @Resource
20 | private CookieInterceptor cookieInterceptor;
21 |
22 | @Override
23 | public void addInterceptors(InterceptorRegistry registry) {
24 | registry.addInterceptor(permissionInterceptor).addPathPatterns("/**");
25 | registry.addInterceptor(cookieInterceptor).addPathPatterns("/**");
26 | super.addInterceptors(registry);
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/resolver/WebExceptionResolver.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.controller.resolver;
2 |
3 | import com.xxl.job.admin.core.util.JacksonUtil;
4 | import com.xxl.job.core.biz.model.ReturnT;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.stereotype.Component;
8 | import org.springframework.web.bind.annotation.ResponseBody;
9 | import org.springframework.web.method.HandlerMethod;
10 | import org.springframework.web.servlet.HandlerExceptionResolver;
11 | import org.springframework.web.servlet.ModelAndView;
12 |
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 | import java.io.IOException;
16 |
17 | /**
18 | * common exception resolver
19 | *
20 | * @author xuxueli 2016-1-6 19:22:18
21 | */
22 | @Component
23 | public class WebExceptionResolver implements HandlerExceptionResolver {
24 | private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class);
25 |
26 | @Override
27 | public ModelAndView resolveException(HttpServletRequest request,
28 | HttpServletResponse response, Object handler, Exception ex) {
29 | logger.error("WebExceptionResolver:{}", ex);
30 |
31 | // if json
32 | boolean isJson = false;
33 | HandlerMethod method = (HandlerMethod)handler;
34 | ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
35 | if (responseBody != null) {
36 | isJson = true;
37 | }
38 |
39 | // error result
40 | ReturnT errorResult = new ReturnT(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "
"));
41 |
42 | // response
43 | ModelAndView mv = new ModelAndView();
44 | if (isJson) {
45 | try {
46 | response.setContentType("application/json;charset=utf-8");
47 | response.getWriter().print(JacksonUtil.writeValueAsString(errorResult));
48 | } catch (IOException e) {
49 | logger.error(e.getMessage(), e);
50 | }
51 | return mv;
52 | } else {
53 |
54 | mv.addObject("exceptionMsg", errorResult.getMsg());
55 | mv.setViewName("/common/common.exception");
56 | return mv;
57 | }
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobDynamicSchedulerConfig.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.conf;
2 |
3 | import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
4 | import org.quartz.Scheduler;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.core.io.ClassPathResource;
8 | import org.springframework.scheduling.quartz.SchedulerFactoryBean;
9 |
10 | import javax.sql.DataSource;
11 |
12 | /**
13 | * @author xuxueli 2018-10-28 00:18:17
14 | */
15 | @Configuration
16 | public class XxlJobDynamicSchedulerConfig {
17 |
18 | @Bean
19 | public SchedulerFactoryBean getSchedulerFactoryBean(DataSource dataSource){
20 |
21 | SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
22 | schedulerFactory.setDataSource(dataSource);
23 | schedulerFactory.setAutoStartup(true); // 自动启动
24 | schedulerFactory.setStartupDelay(20); // 延时启动,应用启动成功后在启动
25 | schedulerFactory.setOverwriteExistingJobs(true); // 覆盖DB中JOB:true、以数据库中已经存在的为准:false
26 | schedulerFactory.setApplicationContextSchedulerContextKey("applicationContext");
27 | schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties"));
28 |
29 | return schedulerFactory;
30 | }
31 |
32 | @Bean(initMethod = "start", destroyMethod = "destroy")
33 | public XxlJobDynamicScheduler getXxlJobDynamicScheduler(SchedulerFactoryBean schedulerFactory){
34 |
35 | Scheduler scheduler = schedulerFactory.getScheduler();
36 |
37 | XxlJobDynamicScheduler xxlJobDynamicScheduler = new XxlJobDynamicScheduler();
38 | xxlJobDynamicScheduler.setScheduler(scheduler);
39 |
40 | return xxlJobDynamicScheduler;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.jobbean;
2 |
3 | import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
4 | import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
5 | import org.quartz.JobExecutionContext;
6 | import org.quartz.JobExecutionException;
7 | import org.quartz.JobKey;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.scheduling.quartz.QuartzJobBean;
11 |
12 | /**
13 | * http job bean
14 | * “@DisallowConcurrentExecution” diable concurrent, thread size can not be only one, better given more
15 | * @author xuxueli 2015-12-17 18:20:34
16 | */
17 | //@DisallowConcurrentExecution
18 | public class RemoteHttpJobBean extends QuartzJobBean {
19 | private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class);
20 |
21 | @Override
22 | protected void executeInternal(JobExecutionContext context)
23 | throws JobExecutionException {
24 |
25 | // load jobId
26 | JobKey jobKey = context.getTrigger().getJobKey();
27 | Integer jobId = Integer.valueOf(jobKey.getName());
28 |
29 | // trigger
30 | JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobGroup.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.model;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | /**
8 | * Created by xuxueli on 16/9/30.
9 | */
10 | public class XxlJobGroup {
11 |
12 | private int id;
13 | private String appName;
14 | private String title;
15 | private int order;
16 | private int addressType; // 执行器地址类型:0=自动注册、1=手动录入
17 | private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
18 |
19 | // registry list
20 | private List registryList; // 执行器地址列表(系统注册)
21 | public List getRegistryList() {
22 | if (addressList!=null && addressList.trim().length()>0) {
23 | registryList = new ArrayList(Arrays.asList(addressList.split(",")));
24 | }
25 | return registryList;
26 | }
27 |
28 | public int getId() {
29 | return id;
30 | }
31 |
32 | public void setId(int id) {
33 | this.id = id;
34 | }
35 |
36 | public String getAppName() {
37 | return appName;
38 | }
39 |
40 | public void setAppName(String appName) {
41 | this.appName = appName;
42 | }
43 |
44 | public String getTitle() {
45 | return title;
46 | }
47 |
48 | public void setTitle(String title) {
49 | this.title = title;
50 | }
51 |
52 | public int getOrder() {
53 | return order;
54 | }
55 |
56 | public void setOrder(int order) {
57 | this.order = order;
58 | }
59 |
60 | public int getAddressType() {
61 | return addressType;
62 | }
63 |
64 | public void setAddressType(int addressType) {
65 | this.addressType = addressType;
66 | }
67 |
68 | public String getAddressList() {
69 | return addressList;
70 | }
71 |
72 | public void setAddressList(String addressList) {
73 | this.addressList = addressList;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.model;
2 |
3 | /**
4 | * xxl-job log for glue, used to track job code process
5 | * @author xuxueli 2016-5-19 17:57:46
6 | */
7 | public class XxlJobLogGlue {
8 |
9 | private int id;
10 | private int jobId; // 任务主键ID
11 | private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
12 | private String glueSource;
13 | private String glueRemark;
14 | private String addTime;
15 | private String updateTime;
16 |
17 | public int getId() {
18 | return id;
19 | }
20 |
21 | public void setId(int id) {
22 | this.id = id;
23 | }
24 |
25 | public int getJobId() {
26 | return jobId;
27 | }
28 |
29 | public void setJobId(int jobId) {
30 | this.jobId = jobId;
31 | }
32 |
33 | public String getGlueType() {
34 | return glueType;
35 | }
36 |
37 | public void setGlueType(String glueType) {
38 | this.glueType = glueType;
39 | }
40 |
41 | public String getGlueSource() {
42 | return glueSource;
43 | }
44 |
45 | public void setGlueSource(String glueSource) {
46 | this.glueSource = glueSource;
47 | }
48 |
49 | public String getGlueRemark() {
50 | return glueRemark;
51 | }
52 |
53 | public void setGlueRemark(String glueRemark) {
54 | this.glueRemark = glueRemark;
55 | }
56 |
57 | public String getAddTime() {
58 | return addTime;
59 | }
60 |
61 | public void setAddTime(String addTime) {
62 | this.addTime = addTime;
63 | }
64 |
65 | public String getUpdateTime() {
66 | return updateTime;
67 | }
68 |
69 | public void setUpdateTime(String updateTime) {
70 | this.updateTime = updateTime;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobRegistry.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.model;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * Created by xuxueli on 16/9/30.
7 | */
8 | public class XxlJobRegistry {
9 |
10 | private int id;
11 | private String registryGroup;
12 | private String registryKey;
13 | private String registryValue;
14 | private Date updateTime;
15 |
16 | public int getId() {
17 | return id;
18 | }
19 |
20 | public void setId(int id) {
21 | this.id = id;
22 | }
23 |
24 | public String getRegistryGroup() {
25 | return registryGroup;
26 | }
27 |
28 | public void setRegistryGroup(String registryGroup) {
29 | this.registryGroup = registryGroup;
30 | }
31 |
32 | public String getRegistryKey() {
33 | return registryKey;
34 | }
35 |
36 | public void setRegistryKey(String registryKey) {
37 | this.registryKey = registryKey;
38 | }
39 |
40 | public String getRegistryValue() {
41 | return registryValue;
42 | }
43 |
44 | public void setRegistryValue(String registryValue) {
45 | this.registryValue = registryValue;
46 | }
47 |
48 | public Date getUpdateTime() {
49 | return updateTime;
50 | }
51 |
52 | public void setUpdateTime(Date updateTime) {
53 | this.updateTime = updateTime;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/quartz/XxlJobThreadPool.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.quartz;
2 |
3 | import org.quartz.SchedulerConfigException;
4 | import org.quartz.spi.ThreadPool;
5 |
6 | /**
7 | * single thread pool, for async trigger
8 | *
9 | * @author xuxueli 2019-03-06
10 | */
11 | public class XxlJobThreadPool implements ThreadPool {
12 |
13 | @Override
14 | public boolean runInThread(Runnable runnable) {
15 |
16 | // async run
17 | runnable.run();
18 | return true;
19 |
20 | //return false;
21 | }
22 |
23 | @Override
24 | public int blockForAvailableThreads() {
25 | return 1;
26 | }
27 |
28 | @Override
29 | public void initialize() throws SchedulerConfigException {
30 |
31 | }
32 |
33 | @Override
34 | public void shutdown(boolean waitForJobsToComplete) {
35 |
36 | }
37 |
38 | @Override
39 | public int getPoolSize() {
40 | return 1;
41 | }
42 |
43 | @Override
44 | public void setInstanceId(String schedInstId) {
45 |
46 | }
47 |
48 | @Override
49 | public void setInstanceName(String schedName) {
50 |
51 | }
52 |
53 | // support
54 | public void setThreadCount(int count) {
55 | //
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route;
2 |
3 | import com.xxl.job.admin.core.route.strategy.*;
4 | import com.xxl.job.admin.core.util.I18nUtil;
5 |
6 | /**
7 | * Created by xuxueli on 17/3/10.
8 | */
9 | public enum ExecutorRouteStrategyEnum {
10 |
11 | FIRST(I18nUtil.getString("jobconf_route_first"), new ExecutorRouteFirst()),
12 | LAST(I18nUtil.getString("jobconf_route_last"), new ExecutorRouteLast()),
13 | ROUND(I18nUtil.getString("jobconf_route_round"), new ExecutorRouteRound()),
14 | RANDOM(I18nUtil.getString("jobconf_route_random"), new ExecutorRouteRandom()),
15 | CONSISTENT_HASH(I18nUtil.getString("jobconf_route_consistenthash"), new ExecutorRouteConsistentHash()),
16 | LEAST_FREQUENTLY_USED(I18nUtil.getString("jobconf_route_lfu"), new ExecutorRouteLFU()),
17 | LEAST_RECENTLY_USED(I18nUtil.getString("jobconf_route_lru"), new ExecutorRouteLRU()),
18 | FAILOVER(I18nUtil.getString("jobconf_route_failover"), new ExecutorRouteFailover()),
19 | BUSYOVER(I18nUtil.getString("jobconf_route_busyover"), new ExecutorRouteBusyover()),
20 | SHARDING_BROADCAST(I18nUtil.getString("jobconf_route_shard"), null);
21 |
22 | ExecutorRouteStrategyEnum(String title, ExecutorRouter router) {
23 | this.title = title;
24 | this.router = router;
25 | }
26 |
27 | private String title;
28 | private ExecutorRouter router;
29 |
30 | public String getTitle() {
31 | return title;
32 | }
33 | public ExecutorRouter getRouter() {
34 | return router;
35 | }
36 |
37 | public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){
38 | if (name != null) {
39 | for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) {
40 | if (item.name().equals(name)) {
41 | return item;
42 | }
43 | }
44 | }
45 | return defaultItem;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route;
2 |
3 | import com.xxl.job.core.biz.model.ReturnT;
4 | import com.xxl.job.core.biz.model.TriggerParam;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by xuxueli on 17/3/10.
12 | */
13 | public abstract class ExecutorRouter {
14 | protected static Logger logger = LoggerFactory.getLogger(ExecutorRouter.class);
15 |
16 | /**
17 | * route address
18 | *
19 | * @param addressList
20 | * @return ReturnT.content=address
21 | */
22 | public abstract ReturnT route(TriggerParam triggerParam, List addressList);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
5 | import com.xxl.job.admin.core.util.I18nUtil;
6 | import com.xxl.job.core.biz.ExecutorBiz;
7 | import com.xxl.job.core.biz.model.ReturnT;
8 | import com.xxl.job.core.biz.model.TriggerParam;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by xuxueli on 17/3/10.
14 | */
15 | public class ExecutorRouteBusyover extends ExecutorRouter {
16 |
17 | @Override
18 | public ReturnT route(TriggerParam triggerParam, List addressList) {
19 | StringBuffer idleBeatResultSB = new StringBuffer();
20 | for (String address : addressList) {
21 | // beat
22 | ReturnT idleBeatResult = null;
23 | try {
24 | ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
25 | idleBeatResult = executorBiz.idleBeat(triggerParam.getJobId());
26 | } catch (Exception e) {
27 | logger.error(e.getMessage(), e);
28 | idleBeatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e );
29 | }
30 | idleBeatResultSB.append( (idleBeatResultSB.length()>0)?"
":"")
31 | .append(I18nUtil.getString("jobconf_idleBeat") + ":")
32 | .append("
address:").append(address)
33 | .append("
code:").append(idleBeatResult.getCode())
34 | .append("
msg:").append(idleBeatResult.getMsg());
35 |
36 | // beat success
37 | if (idleBeatResult.getCode() == ReturnT.SUCCESS_CODE) {
38 | idleBeatResult.setMsg(idleBeatResultSB.toString());
39 | idleBeatResult.setContent(address);
40 | return idleBeatResult;
41 | }
42 | }
43 |
44 | return new ReturnT(ReturnT.FAIL_CODE, idleBeatResultSB.toString());
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
5 | import com.xxl.job.admin.core.util.I18nUtil;
6 | import com.xxl.job.core.biz.ExecutorBiz;
7 | import com.xxl.job.core.biz.model.ReturnT;
8 | import com.xxl.job.core.biz.model.TriggerParam;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by xuxueli on 17/3/10.
14 | */
15 | public class ExecutorRouteFailover extends ExecutorRouter {
16 |
17 | @Override
18 | public ReturnT route(TriggerParam triggerParam, List addressList) {
19 |
20 | StringBuffer beatResultSB = new StringBuffer();
21 | for (String address : addressList) {
22 | // beat
23 | ReturnT beatResult = null;
24 | try {
25 | ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
26 | beatResult = executorBiz.beat();
27 | } catch (Exception e) {
28 | logger.error(e.getMessage(), e);
29 | beatResult = new ReturnT(ReturnT.FAIL_CODE, ""+e );
30 | }
31 | beatResultSB.append( (beatResultSB.length()>0)?"
":"")
32 | .append(I18nUtil.getString("jobconf_beat") + ":")
33 | .append("
address:").append(address)
34 | .append("
code:").append(beatResult.getCode())
35 | .append("
msg:").append(beatResult.getMsg());
36 |
37 | // beat success
38 | if (beatResult.getCode() == ReturnT.SUCCESS_CODE) {
39 |
40 | beatResult.setMsg(beatResultSB.toString());
41 | beatResult.setContent(address);
42 | return beatResult;
43 | }
44 | }
45 | return new ReturnT(ReturnT.FAIL_CODE, beatResultSB.toString());
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.core.biz.model.ReturnT;
5 | import com.xxl.job.core.biz.model.TriggerParam;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by xuxueli on 17/3/10.
11 | */
12 | public class ExecutorRouteFirst extends ExecutorRouter {
13 |
14 | @Override
15 | public ReturnT route(TriggerParam triggerParam, List addressList){
16 | return new ReturnT(addressList.get(0));
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.core.biz.model.ReturnT;
5 | import com.xxl.job.core.biz.model.TriggerParam;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by xuxueli on 17/3/10.
11 | */
12 | public class ExecutorRouteLast extends ExecutorRouter {
13 |
14 | @Override
15 | public ReturnT route(TriggerParam triggerParam, List addressList) {
16 | return new ReturnT(addressList.get(addressList.size()-1));
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.core.biz.model.ReturnT;
5 | import com.xxl.job.core.biz.model.TriggerParam;
6 |
7 | import java.util.List;
8 | import java.util.Random;
9 |
10 | /**
11 | * Created by xuxueli on 17/3/10.
12 | */
13 | public class ExecutorRouteRandom extends ExecutorRouter {
14 |
15 | private static Random localRandom = new Random();
16 |
17 | @Override
18 | public ReturnT route(TriggerParam triggerParam, List addressList) {
19 | String address = addressList.get(localRandom.nextInt(addressList.size()));
20 | return new ReturnT(address);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.route.strategy;
2 |
3 | import com.xxl.job.admin.core.route.ExecutorRouter;
4 | import com.xxl.job.core.biz.model.ReturnT;
5 | import com.xxl.job.core.biz.model.TriggerParam;
6 |
7 | import java.util.List;
8 | import java.util.Random;
9 | import java.util.concurrent.ConcurrentHashMap;
10 |
11 | /**
12 | * Created by xuxueli on 17/3/10.
13 | */
14 | public class ExecutorRouteRound extends ExecutorRouter {
15 |
16 | private static ConcurrentHashMap routeCountEachJob = new ConcurrentHashMap();
17 | private static long CACHE_VALID_TIME = 0;
18 | private static int count(int jobId) {
19 | // cache clear
20 | if (System.currentTimeMillis() > CACHE_VALID_TIME) {
21 | routeCountEachJob.clear();
22 | CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
23 | }
24 |
25 | // count++
26 | Integer count = routeCountEachJob.get(jobId);
27 | count = (count==null || count>1000000)?(new Random().nextInt(100)):++count; // 初始化时主动Random一次,缓解首次压力
28 | routeCountEachJob.put(jobId, count);
29 | return count;
30 | }
31 |
32 | @Override
33 | public ReturnT route(TriggerParam triggerParam, List addressList) {
34 | String address = addressList.get(count(triggerParam.getJobId())%addressList.size());
35 | return new ReturnT(address);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/TriggerTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.trigger;
2 |
3 | import com.xxl.job.admin.core.util.I18nUtil;
4 |
5 | /**
6 | * trigger type enum
7 | *
8 | * @author xuxueli 2018-09-16 04:56:41
9 | */
10 | public enum TriggerTypeEnum {
11 |
12 | MANUAL(I18nUtil.getString("jobconf_trigger_type_manual")),
13 | CRON(I18nUtil.getString("jobconf_trigger_type_cron")),
14 | RETRY(I18nUtil.getString("jobconf_trigger_type_retry")),
15 | PARENT(I18nUtil.getString("jobconf_trigger_type_parent")),
16 | API(I18nUtil.getString("jobconf_trigger_type_api"));
17 |
18 | private TriggerTypeEnum(String title){
19 | this.title = title;
20 | }
21 | private String title;
22 | public String getTitle() {
23 | return title;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/FtlUtil.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.core.util;
2 |
3 | import freemarker.ext.beans.BeansWrapper;
4 | import freemarker.ext.beans.BeansWrapperBuilder;
5 | import freemarker.template.Configuration;
6 | import freemarker.template.TemplateHashModel;
7 |
8 | /**
9 | * ftl util
10 | *
11 | * @author xuxueli 2018-01-17 20:37:48
12 | */
13 | public class FtlUtil {
14 |
15 | private static BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build(); //BeansWrapper.getDefaultInstance();
16 |
17 | public static TemplateHashModel generateStaticModel(String packageName) {
18 | try {
19 | TemplateHashModel staticModels = wrapper.getStaticModels();
20 | TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName);
21 | return fileStatics;
22 | } catch (Exception e) {
23 | e.printStackTrace();
24 | }
25 | return null;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.dao;
2 |
3 | import com.xxl.job.admin.core.model.XxlJobGroup;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by xuxueli on 16/9/30.
11 | */
12 | @Mapper
13 | public interface XxlJobGroupDao {
14 |
15 | public List findAll();
16 |
17 | public List findByAddressType(@Param("addressType") int addressType);
18 |
19 | public int save(XxlJobGroup xxlJobGroup);
20 |
21 | public int update(XxlJobGroup xxlJobGroup);
22 |
23 | public int remove(@Param("id") int id);
24 |
25 | public XxlJobGroup load(@Param("id") int id);
26 | }
27 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.dao;
2 |
3 | import com.xxl.job.admin.core.model.XxlJobInfo;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | import java.util.List;
8 |
9 |
10 | /**
11 | * job info
12 | * @author xuxueli 2016-1-12 18:03:45
13 | */
14 | @Mapper
15 | public interface XxlJobInfoDao {
16 |
17 | public List pageList(@Param("offset") int offset,
18 | @Param("pagesize") int pagesize,
19 | @Param("jobGroup") int jobGroup,
20 | @Param("jobDesc") String jobDesc,
21 | @Param("executorHandler") String executorHandler);
22 | public int pageListCount(@Param("offset") int offset,
23 | @Param("pagesize") int pagesize,
24 | @Param("jobGroup") int jobGroup,
25 | @Param("jobDesc") String jobDesc,
26 | @Param("executorHandler") String executorHandler);
27 |
28 | public int save(XxlJobInfo info);
29 |
30 | public XxlJobInfo loadById(@Param("id") int id);
31 |
32 | public int update(XxlJobInfo item);
33 |
34 | public int delete(@Param("id") int id);
35 |
36 | public List getJobsByGroup(@Param("jobGroup") int jobGroup);
37 |
38 | public int findAllCount();
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobLogGlueDao.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.dao;
2 |
3 | import com.xxl.job.admin.core.model.XxlJobLogGlue;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * job log for glue
11 | * @author xuxueli 2016-5-19 18:04:56
12 | */
13 | @Mapper
14 | public interface XxlJobLogGlueDao {
15 |
16 | public int save(XxlJobLogGlue xxlJobLogGlue);
17 |
18 | public List findByJobId(@Param("jobId") int jobId);
19 |
20 | public int removeOld(@Param("jobId") int jobId, @Param("limit") int limit);
21 |
22 | public int deleteByJobId(@Param("jobId") int jobId);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobRegistryDao.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.dao;
2 |
3 | import com.xxl.job.admin.core.model.XxlJobRegistry;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by xuxueli on 16/9/30.
11 | */
12 | @Mapper
13 | public interface XxlJobRegistryDao {
14 |
15 | public int removeDead(@Param("timeout") int timeout);
16 |
17 | public List findAll(@Param("timeout") int timeout);
18 |
19 | public int registryUpdate(@Param("registryGroup") String registryGroup,
20 | @Param("registryKey") String registryKey,
21 | @Param("registryValue") String registryValue);
22 |
23 | public int registrySave(@Param("registryGroup") String registryGroup,
24 | @Param("registryKey") String registryKey,
25 | @Param("registryValue") String registryValue);
26 |
27 | public int registryDelete(@Param("registryGroup") String registGroup,
28 | @Param("registryKey") String registryKey,
29 | @Param("registryValue") String registryValue);
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/xxl-job/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java:
--------------------------------------------------------------------------------
1 | package com.xxl.job.admin.service;
2 |
3 |
4 | import com.xxl.job.admin.core.model.XxlJobInfo;
5 | import com.xxl.job.core.biz.model.ReturnT;
6 |
7 | import java.util.Date;
8 | import java.util.Map;
9 |
10 | /**
11 | * core job action for xxl-job
12 | *
13 | * @author xuxueli 2016-5-28 15:30:33
14 | */
15 | public interface XxlJobService {
16 |
17 | /**
18 | * page list
19 | *
20 | * @param start
21 | * @param length
22 | * @param jobGroup
23 | * @param jobDesc
24 | * @param executorHandler
25 | * @param filterTime
26 | * @return
27 | */
28 | public Map pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime);
29 |
30 | /**
31 | * add job, default quartz stop
32 | *
33 | * @param jobInfo
34 | * @return
35 | */
36 | public ReturnT add(XxlJobInfo jobInfo);
37 |
38 | /**
39 | * update job, update quartz-cron if started
40 | *
41 | * @param jobInfo
42 | * @return
43 | */
44 | public ReturnT update(XxlJobInfo jobInfo);
45 |
46 | /**
47 | * remove job, unbind quartz
48 | *
49 | * @param id
50 | * @return
51 | */
52 | public ReturnT remove(int id);
53 |
54 | /**
55 | * start job, bind quartz
56 | *
57 | * @param id
58 | * @return
59 | */
60 | public ReturnT start(int id);
61 |
62 | /**
63 | * stop job, unbind quartz
64 | *
65 | * @param id
66 | * @return
67 | */
68 | public ReturnT stop(int id);
69 |
70 | /**
71 | * dashboard info
72 | *
73 | * @return
74 | */
75 | public Map dashboardInfo();
76 |
77 | /**
78 | * chart info
79 | *
80 | * @param startDate
81 | * @param endDate
82 | * @return
83 | */
84 | public ReturnT