Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的 初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不 再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应 用开发领域(rapid application development)成为领导者。
*springboot(微框架) = springmvc(控制器) + spring(项目管理)*
创建独立的Spring应用程序
嵌入的Tomcat,无需部署WAR文件
简化Maven配置
自动配置Spring
没有XML配置
环境要求:
- MAVEN 3.x+
- Spring FrameWork 4.x+
- JDK7.x +
- Spring Boot 1.5.x+
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.7.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
项目中src/main/resources/application.yml
//在项目中创建指定的包结构
/*
com
+| path
+| controller */
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("======hello world=======");
return "hello";
}
}
//在项目中如下的包结构中创建入口类 Application
/*
com
+| */
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8989 (http)
com.path.Application : Started Application in 2.152 seconds (JVM running for 2.611)
//说明: 出现以上日志说明启动成功
//注意: springboot的项目默认没有项目名
//访问路径: http://localhost:8080/hello/hello
server:
port: 8989 #用来指定内嵌服务器端口号
context-path: /springboot #用来指定项目的访问路径
/*说明:
spring boot通常有一个名为 xxxApplication的类,入口类中有一个main方法, 在main方法中使用SpringApplication.run(xxxApplication.class,args)启动springboot应用的项目。
@RestController: 就是@Controller+@ResponseBody组合,支持RESTful访问方 式,返回结果都是json字符串。
@SpringBootApplication 注解等价于:
@Configuration 项目启动时自动配置spring 和 springmvc 初始搭建
@EnableAutoConfiguration 自动与项目中集成的第三方技术进行集成
@ComponentScan 扫描入口类所在子包以及子包后代包中注解(也可以从新指定要扫描哪些包)
*/
#说明: 在实际开发过程中生产环境和测试环境有可能是不一样的 因此将生产中的配置和测试中的配置拆分开,是非常必要的在springboot中也提供了配置文件拆分的方式. 这里以生产中项名名称不一致为例:
生产中项目名为: cmfz
测试中项目名为: springboot
端口同时为: 8080
拆分如下:
#主配置文件:
application.yml #用来书写相同的的配置
server:
port: 8080 #生产和测试为同一个端口
spring:
profiles:
active: prod|dev #需要哪个配置文件则写-后面的短名称
#生产配置文件:
application-pord.yml
server:
context-path: /cmfz
#测试配置文件:
application-dev.yml
server:
context-path: /springboot
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
dependency>
<dependency>
<groupId>org.apache.tomcat.embedgroupId>
<artifactId>tomcat-embed-jasperartifactId>
dependency>
<build>
<finalName>springboot_day1finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
#在配置文件中引入视图解析器
spring:
mvc:
view:
prefix: / # /代表访问项目中webapp中页面
suffix: .jsp
#jsp热部署
server:
port: 8989
context-path: /springboot_day1 #以什么项目名访问
jsp-servlet:
init-parameters:
development: true #开启热部署
http://localhost:8989/cmfz/index.jsp
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.3
commons-dbcp
commons-dbcp
1.4
mysql
mysql-connector-java
5.1.38
>说明:由于springboot整合mybatis版本中默认依赖mybatis 因此不需要额外引入mybati版本,否则会出现冲突
spring:
mvc:
view:
prefix: /
suffix: .jsp
datasource:
type: org.apache.commons.dbcp.BasicDataSource #指定连接池类型
driver-class-name: com.mysql.jdbc.Driver #指定驱动
url: jdbc:mysql://localhost:3306/cmfz #指定url
username: root #指定用户名
password: root #指定密码
#配置文件中加入如下配置:
mybatis:
mapper-locations: classpath:com/path/mapper/*.xml #指定mapper配置文件位置
type-aliases-package: com.path.entity #指定起别名来的类
//入口类中加入如下配置:
@SpringBootApplication
@MapperScan("com.path.dao") //必须在入口类中加入这个配置
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
CREATE TABLE `t_clazz` (
`id` varchar(40) NOT NULL,
`name` varchar(80) DEFAULT NULL,
`no` varchar(90) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class Clazz {
private String id;
private String name;
private String no;
//get set 方法省略....
}
public interface ClazzDAO {
List<Clazz> findAll();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.path.dao.ClazzDAO">
<select id="findAll" resultType="Clazz">
select * from t_clazz
select>
mapper>
//接口
public interface ClazzService {
List<Clazz> findAll();
}
//实现
@Service
@Transactional
public class ClazzServiceImpl implements ClazzService {
@Autowired
private ClazzDAO clazzDAO;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<Clazz> findAll() {
return clazzDAO.findAll();
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestClazzService {
@Autowired
private ClazzService clazzService;
@Test
public void test(){
List<Clazz> all = clazzService.findAll();
for (Clazz clazz : all) {
System.out.println(clazz);
}
}
}
Logback是由log4j创始人设计的又一个开源日志组件。目前,logback分为三个模块:logback-core,logback-classic和logback-access。是对log4j日志展示进一步改进
> DEBUG < INFO < WARN < ERROR
>
> 日志级别由低到高: 日志级别越高输出的日志信息越少
> 日志分为两类
>
> 一种是rootLogger : 用来监听项目中所有的运行日志 包括引入依赖jar中的日志
>
> 一种是logger : 用来监听项目中指定包中的日志信息
> logback的配置文件必须放在项目根目录中 且名字必须为logback.xml
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern> [%p] %d{yyyy-MM-dd HH:mm:ss} %m %npattern>
layout>
appender>
<root level="INFO">
<appender-ref ref="stdout"/>
root>
<logger name="com.path.dao" level="DEBUG"/>
configuration>
@Controller
@RequestMapping("/hello")
public class HelloController {
//声明日志成员
private static Logger logger = Logger.getLogger(HelloController.class);
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("======hello world=======");
logger.debug("DEBUG");
logger.info("INFO");
logger.warn("WARN");
logger.error("ERROR");
return "hello";
}
}
springboot是对原有项目中spring框架和springmvc的进一步封装,因此在springboot中同样支持spring框架中AOP切面编程,不过在springboot中为了快速开发仅仅提供了注解方式的切面编程.
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
/**
@Aspect 用来类上,代表这个类是一个切面
@Before 用在方法上代表这个方法是一个前置通知方法
@After 用在方法上代表这个方法是一个后置通知方法 @Around 用在方法上代表这个方法是一个环绕的方法
@Around 用在方法上代表这个方法是一个环绕的方法
@order(数字)用在类上,数字越小进入越早
**/
/**
环绕,前置,后置全部存在
先进入环绕,在进入前置,离开前置,离开环绕,进入后置,离开后置
**/
@Aspect
@Component
public class MyAspect {
@Before("execution(* com.path.service.*.*(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知");
joinPoint.getTarget();//目标对象
joinPoint.getSignature();//方法签名
joinPoint.getArgs();//方法参数
}
}
@Aspect
@Component
public class MyAspect {
@After("execution(* com.path.service.*.*(..))")
public void before(JoinPoint joinPoint){
System.out.println("后置通知");
joinPoint.getTarget();//目标对象
joinPoint.getSignature();//方法签名
joinPoint.getArgs();//方法参数
}
}
> **注意: 前置通知和后置通知都没有返回值,方法参数都为joinpoint**
@Aspect
@Component
public class MyAspect {
@Around("execution(* com.path.service.*.*(..))")
public Object before(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("进入环绕通知");
proceedingJoinPoint.getTarget();//目标对象
proceedingJoinPoint.getSignature();//方法签名
proceedingJoinPoint.getArgs();//方法参数
Object proceed = proceedingJoinPoint.proceed();//放行执行目标方法
System.out.println("目标方法执行之后回到环绕通知");
return proceed;//返回目标方法返回值
}
}
注意: 环绕通知存在返回值,参数为ProceedingJoinPoint,如果执行放行,不会执行目标方法,一旦放行必须将目标方法的返回值返回,否则调用者无法接受返回数据**
<form action="路径...." method="post" enctype="multipart/form-data">
<input type="file" name="aa">
<input type="submit" value="上传">
form>
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/upload")
public String upload(MultipartFile aa, HttpServletRequest request) throws IOException {
String realPath = request.getRealPath("/upload");
aa.transferTo(new File(realPath,aa.getOriginalFilename()));//文件上传
return "index";
}
}
#上传时出现如下异常: 上传文件的大小超出默认配置 默认10M
nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (38443713) exceeds the configured maximum (10485760)
#修改上传文件大小:
spring:
http:
multipart:
max-file-size: 209715200 #单位是字节
<a href="../file/download?fileName=corejava.txt">corejava.txta>
@RequestMapping("/download")
public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
String realPath = request.getRealPath("/upload");
FileInputStream is = new FileInputStream(new File(realPath, fileName));
ServletOutputStream os = response.getOutputStream();
response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
IOUtils.copy(is,os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
@Configuration(将此类交给工厂创建对象)
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
System.out.println("======1=====");
return true;//返回true 放行 返回false阻止
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("=====2=====");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
System.out.println("=====3=====");
}
}
@Component|@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(myInterceptor)
.addPathPatterns("/**")//定义拦截路径
.excludePathPatterns("/hello/**"); //排除拦截路径(也可以不排除)
}
}
以上是springboot 2.0 版本之前的拦截器,无法拦截页面。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public SecurityInterceptor getSecurityInterceptor() {
return new SecurityInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(getSecurityInterceptor())
.addPathPatterns("/learning/panel_user/login.html");//定义拦截路径
}
}
private class SecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws IOException {
HttpSession session = request.getSession();
Object currentUser = session.getAttribute("currentUser");
if(currentUser==null){
response.sendRedirect("http://localhost:9999/user/dialog.html");
return false;
}
return true;
}
}