1. 什么是Spring Boot
1.1 spring
- Spring 诞生时是 Java 企业版(Java Enterprise Edition,JEE,也称 J2EE)的轻量级代替品。无需开发重量级的 Enterprise JavaBean(EJB),Spring 为企业级 Java 开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的 Java 对象(Plain Old Java Object,POJO)实现了 EJB 的功能。
spring的不足 :
1. 虽然 Spring 的组件代码是轻量级的,但它的配置却是重量级的, 大量的xml配置文件
2. 开发人员需要自行进行项目的依赖管理, 选择合理版本, 避免冲突, 避免不兼容等问题
以上问题都损耗了大量的写代码的时间 .
1.2 Spring Boot
- Spring Boot 让 spring 的不足成为了过去。
- Spring Boot 是 Spring 社区较新的一个项目。该项目的目的是帮助开发者更容易的创建 基于 Spring 的应用程序和服务,让更多人的人更快的对 Spring进行入门体验,为 Spring 生态系统提供了一种固定的、约定优于配置风格的框架。
Spring Boot 具有如下特性:
(1)为基于 Spring 的开发提供更快的入门体验
(2)开箱即用,没有代码生成,也无需 XML配置。同时也可以修改默认值来满足特定的需求。
(3)提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等。
(4)Spring Boot 并不是不对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方式。
2. Spring Boot 入门小 Demo
- 创建 Maven 工程 springboot-demo(打包方式 jar), 目录结构如下
controller, service, dao
必须处于主函数子包中, 因为
controller, service, dao
必须被
spring
扫描,扫描后将会被
spring
容器管理.
2.1 添加依赖
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.4.0.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-activemqartifactId>
dependency>
dependencies>
2.2 创建 application.properties 文件
#修改内置Tomcat的端口配置, 默认端口8080
server.port=80
#自定义参数
url = http:
#配置自己的activeMQ地址
spring.activemq.broker-url=tcp:
注意
:
1. 文件名必须叫 application.properties
2. 需放在 resource
的根目录下, 默认扫描此包中的 application.properties
2.3 引导类
- 创建引导类
MyAppplication.java
, 只需要创建一个引导类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @SpringBootApplication 其实就是以下三个注解的总和
* @Configuration: 用于定义一个配置类
* @EnableAutoConfiguration :Spring Boot 会自动根据你 jar 包的依赖来自动配置项目。
* @ComponentScan: 告诉Spring 哪个 packages 的用注解标识的类会被spring 自动扫描并且装入 bean 容器。
*/
@SpringBootApplication
public class MyAppplication {
public static void main(String[] args) {
SpringApplication.run(MyAppplication.class,args);
}
}
2.4 直接写 Controller 类
import com.pojo.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.resources.Messages_pt_BR;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UserController {
@Autowired
private Environment env;
/**
* 需求:springboot入门
*/
@RequestMapping("/hello")
public String showHello1(){
return "hello,springboot!";
}
/**
* 需求:Restful风格
*/
@RequestMapping("/hello2/{name}")
public String showHello2(@PathVariable String name){
return "hello,springboot!"+name;
}
/**
* 需求:获得配置文件 application.properties 文件中的自定义参数 url
*/
@RequestMapping("/hello3")
public String showHello3(){
return "hello,springboot! url = "+env.getProperty("url");
}
/**
* 需求:展示对象
*/
@RequestMapping("hello4")
public Person showHello4(){
Person p = new Person();
p.setId(1000);
p.setName("张三丰");
return p;
}
/**
* 需求:使用springboot框架内置MQ消息服务器发送及接受消息
* 默认使用 point-to-point 模式
*/
@Autowired
private JmsTemplate jmsTemplate;
@RequestMapping("send/{message}")
public String sendMessage(@PathVariable String message){
jmsTemplate.convertAndSend("oneQueue",message);
return "success";
}
@JmsListener(destination = "oneQueue")
public void receiveMessage(String message){
System.out.println("接受消息:"+message);
}
}
3. 短信微服务
- 整合activeMQ, 基于阿里大于发短信
- 创建微服务模块 springboot-sms 结构目录如下:

3.1 配置文件
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.4.0.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-activemqartifactId>
dependency>
<dependency>
<groupId>com.aliyungroupId>
<artifactId>aliyun-java-sdk-dysmsapiartifactId>
<version>1.0.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.aliyungroupId>
<artifactId>aliyun-java-sdk-coreartifactId>
<version>3.2.5version>
dependency>
dependencies>
- 创建 application.properties
#整合mq
spring.activemq.broker-url=tcp:
#发送短信秘钥
AccessKeyID=SQD6Aw6mg*****
accessKeySecret=KFCVQ32sJmf3Yov*****
3.2 引导类 SmsApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SmsApplication {
public static void main(String[] args) {
SpringApplication.run(SmsApplication.class,args);
}
}
3.3 工具类 SmsUtils.java
import com.aliyuncs.DefaultAcsClient
import com.aliyuncs.IAcsClient
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse
import com.aliyuncs.exceptions.ClientException
import com.aliyuncs.profile.DefaultProfile
import com.aliyuncs.profile.IClientProfile
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.env.Environment
import org.springframework.stereotype.Component
import java.text.SimpleDateFormat
import java.util.Date
@Component
public class SmsUtils {
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi"
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com"
@Autowired
private Environment env
public SendSmsResponse sendSms(String phoneNum,String signName,String templateCode,String code) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000")
System.setProperty("sun.net.client.defaultReadTimeout", "10000")
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", env.getProperty("AccessKeyID"), env.getProperty("accessKeySecret"))
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain)
IAcsClient acsClient = new DefaultAcsClient(profile)
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest()
//必填:待发送手机号
request.setPhoneNumbers(phoneNum)
//必填:短信签名-可在短信控制台中找到
request.setSignName(signName)
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode)
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
request.setTemplateParam("{\"code\":\""+ code +"\"}")
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997")
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId")
//hint 此处可能会抛出异常,注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request)
return sendSmsResponse
}
public QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000")
System.setProperty("sun.net.client.defaultReadTimeout", "10000")
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", env.getProperty("AccessKeyID"), env.getProperty("accessKeySecret"))
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain)
IAcsClient acsClient = new DefaultAcsClient(profile)
//组装请求对象
QuerySendDetailsRequest request = new QuerySendDetailsRequest()
//必填-号码
request.setPhoneNumber("15000000000")
//可选-流水号
request.setBizId(bizId)
//必填-发送日期 支持30天内记录查询,格式yyyyMMdd
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd")
request.setSendDate(ft.format(new Date()))
//必填-页大小
request.setPageSize(10L)
//必填-当前页码从1开始计数
request.setCurrentPage(1L)
//hint 此处可能会抛出异常,注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request)
return querySendDetailsResponse
}
}
3.4 监听类 SmsListener.java
import com.aliyuncs.exceptions.ClientException;
import com.utils.SmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class SmsListener {
@Autowired
private SmsUtils smsUtils;
@JmsListener(destination = "sms")
public void sendSms(Map map){
try {
String sign_name = (String) map.get("sign_name");
String template_code = (String) map.get("template_code");
String code = (String) map.get("code");
String phone = (String) map.get("phone");
smsUtils.sendSms(sign_name,template_code,code,phone);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.4 测试
signName=十里
templateCode=SMS_1250
- 配置文件 applicationContext-mq-producer.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="targetConnnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<constructor-arg name="brokerURL" value="tcp://139.199.***.***:61616"/>
bean>
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="targetConnnectionFactory"/>
bean>
<bean class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
bean>
<bean class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="sms"/>
bean>
beans>
- 在模块 user-service (war) 中的 UserServiceImpl 类中加入方法测试:
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private RedisTemplate redisTemplate;
@Value("${signName}")
private String signName;
@Value("${templateCode}")
private String templateCode;
/**
* 发送手机验证码
* 需要向activeMQ中的sms存map集合key包含: String phoneNum, String signName, String templateCode, String code
*
* @param phoneNum 手机号
*/
@RequestMapping("/send/sms/{phoneNum}")
public void sendSms(@PathVariable String phoneNum) {
try {
signName = new String(signName.getBytes("ISO-8859-1"), "utf-8");
String code = String.valueOf((long) (Math.random() * 1000000));
redisTemplate.boundHashOps("phoneCode").put(phoneNum, code);
redisTemplate.boundHashOps("phoneCode").expire(5, TimeUnit.MINUTES);
HashMap map = new HashMap<>();
map.put("phoneNum", phoneNum);
map.put("signName", signName);
map.put("templateCode", templateCode);
map.put("code", code);
jmsTemplate.convertAndSend("sms", map);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}