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.boot</groupId >
<artifactId > spring-boot-starter-parent</artifactId >
<version > 1.4.0.RELEASE</version >
</parent >
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-devtools</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-activemq</artifactId >
</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.pyg.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.boot</groupId >
<artifactId > spring-boot-starter-parent</artifactId >
<version > 1.4.0.RELEASE</version >
</parent >
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-activemq</artifactId >
</dependency >
<dependency >
<groupId > com.aliyun</groupId >
<artifactId > aliyun-java-sdk-dysmsapi</artifactId >
<version > 1.0.0-SNAPSHOT</version >
</dependency >
<dependency >
<groupId > com.aliyun</groupId >
<artifactId > aliyun-java-sdk-core</artifactId >
<version > 3.2.5</version >
</dependency >
</dependencies >
创建 application.properties
#整合mq
spring.activemq.broker-url=tcp:
#发送短信秘钥
AccessKeyID=SQD6Aw6mgLV
accessKeySecret=KFCVQ32sJmf3Yov8qRE
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 .v 20170525.QuerySendDetailsRequest
import com .aliyuncs .dysmsapi .model .v 20170525.QuerySendDetailsResponse
import com .aliyuncs .dysmsapi .model .v 20170525.SendSmsRequest
import com .aliyuncs .dysmsapi .model .v 20170525.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 (10 L)
//必填-当前页码从1 开始计数
request.setCurrentPage (1 L)
//hint 此处可能会抛出异常,注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse (request)
return querySendDetailsResponse
}
}
3.4 监听类 SmsListener.java
import com. aliyuncs. exceptions. ClientException;
import com. pyg. 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
在模块 user-service 中的 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<String, String> 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();
}
}