L1、hello spring boot
一、创建maven项目
new==>spring-starter-project
二、添加父级依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath /> <!--lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
三、入口类
//springboot 会自动扫描@SpringBootApplication所在的同级包,建议入口类放在//groupId+artifactid组合的包名下
//@SpringBootApplication组合了@Configuration,@EnableAutoConfiguration,@Configuration
@SpringBootApplication
@RestController //@RestController相当于@Controller+@ResponseBody
public classDemoApplication {
@RequestMapping("/")
public String index() {
return "hello spring boot";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
/*如果要关闭图案,new*SpringApplicationBuilder(CityInfoApplication.class).bannerMode(Mod/*/e.OFF).run(args);
}
}
四、运行
mvnspring-boot:run
或者打包成jar,在其目录下运行java –jarproject.jar
L2、application.properties
一、修改端口号、访问路径、字符编码
在src/main/resources目录新建application.properties文件
server.port=9090
server.context-path=/helloboot
spring.http.encoding.charset=UTF-8默认为UTF-8
二、设置日志
springboot 默认使用logback作为日志框架
日志级别的由高到低的顺序是DEBUG、INFO、WARN、ERROR、FATAL
在application.properties文件中配置
logging.file=log/CityInfo.log
logging.level.org.springframework.web: ERROR
logging.level.org.hibernate: ERROR
或者将logback.xml文件放到src\main\resources下
在类中添加
importorg.apache.commons.logging.*;
private static Log log = LogFactory.getLog(TestCore.class);
在方法里使用
public void log() {
log.debug("debug1");
log.info("info1");
log.warn("warn1");
log.error("error1");
log.fatal("fatal1");
}
三、@Value注入属性
在application.properties中添加属性
如 book.name=majy
在类的属性上添加@Value(“${book.name}”)
四、Profile配置不同环境
在src/resources下新建
application-dev.properties其中server.port=80
application-prod.properties其中server.port=8888
在application.properties中指定开发环境 spring.profiles.active=dev
若有重复的属性,制定后的application-dev.properties会覆盖application.properties属性
五、添加配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Bean
@ConfigurationProperties(prefix="keys.db")//在application.properties中注册keys.db前缀,可设置属性
public DataSource dataSource()throwsPropertyVetoException {
BasicDataSourcedb = new BasicDataSource();
db.setDriverClassName("com.mysql.jdbc.Driver");
// 配置连接池的初始值,连接池启动时创建的初始化连接数量(默认值为0)
// db.setInitialSize(1);
// 当最小空闲时,当连接少于minIdle时会自动去申请一些连接
db.setMinIdle(1);
// 连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
db.setMaxActive(100);
// 最大空闲时,当经过一个高峰之后,连接池可以将一些用不到的连接释放,一直减少到maxIdle为止
db.setMaxIdle(20);
// 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限)以毫秒为单位
db.setMaxWait(60000);
// 是否自动回收超时连接
db.setRemoveAbandoned(true);
// 超时时间(以秒数为单位
db.setRemoveAbandonedTimeout(180);
// 代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接
db.setNumTestsPerEvictionRun(100);
return db;
}
在application.properties中添加
keys.db.url=jdbc:mysql://localhost:3306/project_t?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
keys.db.username=root
keys.db.password=000000
L3、web开发
一、注册Servlet、Filter、Listener
通过ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean注册
例如
@Bean
public ServletRegistrationBeandruidServlet() {
ServletRegistrationBeanregistrationBean= newServletRegistrationBean(new DruidServlet(), "/druid/*");
Map<String,String> params= newHashMap<>();
params.put("resetEnable","true");
params.put("loginUsername",DruidConfig.username);
params.put("loginPassword",DruidConfig.password);
params.put("allow",DruidConfig.allow);
registrationBean.setInitParameters(params);
return registrationBean;
}
二、tomcat配置
在application.properties中添加
server.port=端口
server.session-timeout=会话过期时间,单位为秒
server.context-path=访问路径,默认为/
三、静态资源路径
1、html
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
根据默认原则,脚本样式图片,、html页面等静态资源应放置在src/main/resources/static下;
@EnableWebMvc
@Configuration
public classMyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public voidaddResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(
"classpath:/static/");
//ResourceHandler是访问路径,ResourceLocations是文件目录
}
@Override
public voidaddViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index.html");
//ViewController是访问路径,ViewName是文件目录简写
}
@Override
public voidaddInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(newMyInterceptor()).addPathPatterns("/user/**");//拦截user/路径
}
//可不忽略路径中“.”后的参数
@Override
public void configurePathMatch(PathMatchConfigurerconfigurer){
configurer.setUseSuffixPatternMatch(false);
}
}
四、配置错误页面
实现EmbeddedServletContainerCustomizer
@Component
publicclass CustomServletContainer implements EmbeddedServletContainerCustomizer{
@Override
public voidcustomize(ConfigurableEmbeddedServletContainer container) {
container.setPort(8888);
container.addErrorPages(newErrorPage(HttpStatus.NOT_FOUND, "/404.html"));
container.addErrorPages(newErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/500.html"));
container.setSessionTimeout(10,TimeUnit.MINUTES);
}
}
其中404.html和500.html在src/main/resources/static/下即可
五、设置自己的Favicon
如果要关闭favicon,在application.properties中设置spring.mvc.favicon.enabled=false;
如果要替换,只要将favicon.ico放在src/main/resources/static/下
六、HTTPS设置
1、生成证书
keytool-genkey -alias tomcat
在用户目录生成.keystore文件,拷贝到项目跟目录
2、配置application.properties
server.ssl.key-store=.keystore
server.ssl.key-password=000000
server.ssl.key-store-type=JKS
server.ssl.key-alias=tomcat
七、替换为jetty服务器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 添加exclusions -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<!-- 将spring-boot-starter-tomcat修改为spring-boot-starter-jetty -->
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
八、跨域设置
添加拦截器
public classOriginInterceptor extends HandlerInterceptorAdapter {
@Override
public booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//第二个参数为允许访问的域名
response.setHeader("Access-Control-Allow-Origin", "http://localhost");
return super.preHandle(request, response, handler);
}
}
registry.addInterceptor(new OriginInterceptor()).addPathPatterns("/**");
九、设置首页
@Configuration
public classMvcConfig extendsWebMvcConfigurerAdapter {
@Override
public voidaddResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
// ResourceHandler是访问路径,ResourceLocations是文件目录
}
}
@Controller
public classIndexController {
@RequestMapping("/")
public String login() {
//login.html在resources/static下
return "login.html";
}
}
L4、数据访问
一、spring datajpa
1、 添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.1.0.7.0</version>
</dependency>
2、 配置application.properties
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc\:oracle\:thin\:@localhost\:1521\:xe
spring.datasource.username=
spring.datasource.password=
//mysql:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/project_t?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username=
spring.datasource.password=
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
3、 Entity
注意,在有OneToMany和ManyToOne中,会发生无限循环的场景,如何破?
在类上添加@JsonIgnoreProperties(ignoreUnknown=true,value="users")
Json日期转换
@Column(name = "create_time")
@JsonFormat(pattern = "yyyy-MM-ddHH:mm", timezone = "GMT+08:00")
private Timestamp createTime;
二、事务
spring datajpa对所有默认方法都开启了事务支持,且查询类事务默认启用readOnly=true属性,可以查看SimpleJpaRepository,在spring boot中无需显示开启使用@EnableTransactionManagement注解
在@Service类或方法上添加@Transactional(rollbackFor= Throwable.class)
三、自动提供的了Bean
@Autowired
JdbcTemplatejdbcTemplate;
@PersistenceContext
EntityManagerentityManager;
四、数据缓存
1、概述
a) spring boot将CacheManager自动配置在org.springframework.boot.autoconfigure.cache包中,提供多个CacheManager实现,默认使用SimpleCacheConfiguration即使用ConcurrentMapCacheManager
b) Spring boot支持以“spring.cache”为前缀的属性配置缓存
c) 在springboot环境中,只需要导入缓存技术的依赖包spring-boot-starter-cache,并配置@EnableCaching开启缓存支持即可
2、声明式缓存注解
注解 | 解释 |
@Cacheable | 在方法执行前先查看缓存中是否有数据,若有数据,直接返回缓存数据;若没有数据,调用方法并将返回值放进缓存 |
@CachePut | 无论如何,都将返回值放进缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
@Caching | 组合多个注解到一个方法上 |
@Cacheable、@CachePut、@CacheEvict都有key和value属性,指定缓存中存储的键和缓存名称
@Cacheable注解有三个参数,value是必须的,还有key和condition。第一个参数,也就是value指明了缓存将被存到什么地方。任何存储在缓存中的数据为了高速访问都需要一个key。spring默认使用被@Cacheable注解的方法的签名来作为key,当然你可以重写key,自定义key可以使用SpEL表达式。Key属性以#开头后接参数名[.属性],如果没有指定key,则方法参数作为key保存到缓存中
3、案例
//将数据新增或更新到缓存,缓存名称为*people,数据的key是people的id
@CachePut(value=”people”,key=”#persion.id”)
publicPersion save(Persion persion){
return persionDao.save(persion);
}
//从缓存people中删除key为id的数据
@CacheEvict(value=”people”)
publicvoid delete(Long id){
persionDao.delete(id);
}
L5、测试
一、测试业务层
在src/test/java下定义测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public classTestUserBo {
@Autowired
UserBouserBo;
@Test
public void testFindAll() {
List<User>users= userBo.findUsers();
for (User user : users) {
System.out.println(user.getName());
}
}
}
二、测试Controller层
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import staticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public classTestController {
MockMvcmockMvc;
@Autowired
WebApplicationContextwac;
@Before // 在测试前做初始化工作
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void indexFindTypes() throws Exception {
MvcResultresult= mockMvc.perform(post("/findTypes?callback=cal")).andReturn();
log.info(result.getResponse().getStatus());
log.info(result.getResponse().getContentAsString());
}
private static final Log log = LogFactory.getLog(TestController.class);
}
L6、WebSocket
一、概述
1、WebSocket为浏览器和服务器提供双工异步通信的功能,即浏览器和服务器可以互相发送消息。我们使用它的子协议STOMP,它是更高级别的协议
2、添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
3、需要导入sockjs.min.js和stomp.min.js
二、设置端点和代理
@Configuration
@EnableWebSocketMessageBroker
// @EnableWebSocketMessageBroker开启STOMP协议来传输基于代理的消息
public classWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
// 注册STOMP协议的endpoint,映射指定的url,指定使用SockJS协议
@Override
public voidregisterStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/PTPPoint").withSockJS();//点对点式端点
registry.addEndpoint("/BCPoint").setAllowedOrigins("http://localhost").withSockJS().setStreamBytesLimit(512* 1024).setHttpMessageCacheSize(1000).setDisconnectDelay(30 * 1000); // 广播式端点
}
// 广播式应配置消息代理
@Override
public voidconfigureMessageBroker(MessageBrokerRegistry registry) {
//广播式代理和点对点式代理
registry.enableSimpleBroker("/BCBroker","/PTPBroker");
}
}
三、自定义pojo类
public classMessage {
private String content;
}
四、广播式
1、Controller类
@Controller
public classBroadcastSocket {
// 当浏览器向服务器发送请求时,通过@MessageMapping映射/BCSend这个地址,类似于RequestMapping
// 当服务器有消息时,会对订阅了@SendTo中的路径的浏览器发送消息
@MessageMapping("/BCSend")
@SendTo("/BCBroker/send")
public Message say(Message message) {
return new Message("你好:" + message.getContent());
}
}
2、javascript
// 定义全局对象
var StompClient = null, Sock = null;
$('#btnConnect').unbind('click').click(function() {
// 连接SockJS的endpoint名称
Sock= newSockJS('/BCPoint');
// 使用STOMP协议的WebSocket客户端
StompClient= Stomp.over(Sock);
// 连接WebSocket服务器
StompClient.connect({},function(frame){
// 客户端通过subscribe方法订阅/BCBroker/send目标发送消息,这个是在控制器的@SendTo定义的
StompClient.subscribe('/BCBroker/send', function(response) {
$('#output').append(JSON.parse(response.body).content+ "</br>");
});
});
});
$('#btnStop').unbind('click').click(function() {
if (StompClient) {
StompClient.disconnect();
}
});
$('#btnSend').unbind('click').click(function() {
var msg = $('#msg').val();
// 客户端向/hello目标发送消息,这个是在控制器@MessageMapping中定义
StompClient.send("/BCSend",{}, JSON.stringify({
"content": msg
}));
});
五、点对点式
1、用spring security配置登录
@Override
protected voidconfigure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("000000").roles("USER").and().withUser("user2")
.password("000000").roles("USER");
}
2、Controller类
@Controller
public classPointSocket {
// 通过SimpleMessageTemplate向浏览器发送信息
@Autowired
SimpMessagingTemplatetemplate;
// 可直接获取principal,包含当前用户信息
// 当浏览器向服务器发送请求时,通过@MessageMapping映射/chat这个地址,类似于RequestMapping
@MessageMapping("/chat")
public void chat(Principal principal, Message msg) {
msg.setContent(principal.getName() + ":" + msg.getContent());
// 如果发送人事user1,则发送给user2;如果发送人是user2,则发送给user1。
if (principal.getName().equals("user1")){
// 通过该方法发送信息,第一个参数是接收消息的用户,第二个参数是浏览器订阅地址,第三个参数是消息本身
template.convertAndSendToUser("user2","/PTPBroker/notifications", msg);
}
if (principal.getName().equals("user2")){
template.convertAndSendToUser("user1","/PTPBroker/notifications", msg);
}
}
}
3、js
// 定义全局对象
var Sock = null,StompClient = null;
$("#btnConnect").unbind('click').click(
function() {
// 连接endpoint名称为/PTPPoint
Sock= newSockJS("/PTPPoint");
StompClient= Stomp.over(Sock);
StompClient.connect('guest', 'guest', function(frame) {
// 订阅/user/PTPBroker/notifications发送的信息,与控制器中messageTemplate一致,多一个user,有了user才能发送到指定的用户
StompClient.subscribe('/user/PTPBroker/notifications',
function(response) {
var msg =JSON.parse(response.body).content;
$('#output').append("Received:"+ msg + "<br/>");
});
});
});
$('#btnSend').unbind('click').click(function() {
var msg = $('#msg').val();
StompClient.send('/chat', {}, JSON.stringify({
"content": msg
}));
});
$('#btnStop').unbind('click').click(function() {
Sock.close();
$('#output').html('');
});
L7、Spring Data REST
一、概述
1、 可以将repository自动输出为REST资源。
2、 配置定义在RepositoryRestMvcConfiguration,配置类中依据定义好了,我们可以继承此类或者使用@Import导入此类
3、 在Spring boot中,通过SpringBootRepositoryRestConfigurer源码可以看到已经配置好了,只需要添加spring-boot-starter-data-rest依赖,无须任何配置
二、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
三、配置application.properties
可以省略
spring.data.rest.为前缀属性配置RestoryRestConfiguration
#设置rest资源基本路径,变为http://localhost:9090/api
spring.data.rest.base-path=/api
spring.data.rest.default-page-size=10
spring.data.rest.return-body-on-create=true
spring.data.rest.return-body-on-update=true
四、测试
显示全部rest接口http://localhost:9090/
查询info列表http://localhost:9090/infoes //对应Info对象的复数形式
分页排序查询info列表http://localhost:9090/infoes?page=0&size=3&sort=createTime,desc
查询单个info对象http://localhost:9090/infoes/id
显示查询接口中的方法http://localhost:9090/infoes/search
保存:向http://localhost:9090/infoes发送post请求,传递json参数
更新:向http://localhost:9090/infoes/id发送put请求,传递json参数
删除:向http://localhost:9090/infoes/id发送delete请求
根据自定义方法查询
http://localhost:9090/infoes/search/findByTitleStartsWith?title=t
@RestResource
Page<Info>findByTitleStartsWith(@Param("title")String title,Pageable pageable);
L8、部署
所谓热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用
一、热部署
1、模板引擎热部署
模板引擎默认是开启缓存的,可以将缓存关闭
在application.protertises里关闭
spring.thymeleaf.cache=false
2、java类文件热部署
三、spring boot 热启动
添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
或者
spring loaded可实现修改类文件的热部署。
从https://github.com/spring-projects/spring-loaded下载springloaded-1.2.5.RELEASE.jar
在eclipse runconfiguration的vm arguments中填写如下内容
-javaagent:D:/springloaded-1.2.5.RELEASE.jar-noverify
或者
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
二、运行
打包跳过测试
mvn install -DskipTests
mvn install -Dmaven.test.skip=true
mvnspring-boot:run
或者打包成jar或者war,在其目录下运行java –jar project.jar或java -jar project.war
在Centos上运行,并打印日志到文件nohup.out
nohupmvn spring-boot:run &
三、在tomcat中运行
@SpringBootApplication
public classProjectTApplication extendsSpringBootServletInitializer{
/**
* 在tomcat运行需要继承SpringBootServletInitializer实现configure方法
*/
@Override
protected SpringApplicationBuilderconfigure(SpringApplicationBuilder application) {
return application.sources(ProjectTApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ProjectTApplication.class, args);
}
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
把webapps下的文件删除,把要部署的war包重命名为ROOT.war
L9、监控
1、在pom.xml中添加
<dependency>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、在application.properties中添加
management.security.enabled=true
3、可以查看
/mappings
/health