Spring Boot入门第二篇

第一天的详见:https://www.cnblogs.com/LBJLAKERS/p/12001253.html

  • 同样是新建一个pring Initializer快速创建Spring Boot项目.
  • 在resource的目录下新建两个application-dev.properties/application-pro.properties属性文件分别代表开发环境和生产环境。如图:

指定使用的属性配置文件

一:通过默认的application.properties指定。

  • 可以在默认的application.properties的文件中激活某个文件:

    #正式环境
    #表示激活的是哪一个属性文件
    spring.profiles.active=pro
  • 在dev的属性文件可以配置端口为:
     #开发环境
    server.port=
  • 在Pro的属性文件可以配置端口号为:
    #生产环境
    server.port=

  使用以上的方式如果去运行程序的话,在控制台就会显示激活pro的属性文件,使用的pro的端口

二:如果没有application.properties的属性文件,那么可以通过配置的方式来配置。虚拟机参数;

如上图所示的VM options的配置即可。

三、使用命令行的方式激活使用的属性配置文件。

  • 打包项目为jar包,在cmd的命令窗口切换到jar包的目录,使用命令:

    java -jar spring-boot-config-0.0.-SNAPSHOT.jar --spring.profiles.active=dev;

yml支持的多文档模块方式。

  使用(---)两个横线的方式将文档分割成三个文档的模式。使用这种方式可以激活dev模块的文档

 spring:
profiles:
active: dev
---
server:
port:
spring:
profiles: dev ---
server:
port:
spring:
profiles: pro

 配置文件加载位置

  springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文。

  在项目中加载的顺序为:(优先级由高到底,高优先级的配置会覆盖低优先级的配置;SpringBoot会从这四个位置全部加载主配置文件;互补配置;)

   

  le:./config/
  –file:./
  –classpath:/config/
  –classpath:/

  注意:一般将配置文件放在resources目录下,这样在打包的时候就直接会将配置文件一同打包,否则不能够将配置文件一起打包为jar。并且所有的配置都可以在命令行上进行指定,

     例如在cmd的命令窗口下:java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar

     如果非要将application.properties的配置文件放到非resources的目录下,在cmd的命令窗口可以这样指定:

java -jar spring-boot--config--0.0.-SNAPSHOT.jar  --spring.config.location=配置文件存放的位置  --配置文件中的配置

    这样才能生效

    参看文档:https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#boot-features-external-config

自动配置文件的原理:

  • SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
  • @EnableAutoConfiguration 作用:
    • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件?
    • 可以查看selectImports()方法的内容;
    • List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
  • 可以在在项目的External Libraries中下的spring.factories文件中查看配置。

    例如找到其中以下的:

    org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\

   解读配置文件

@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的
ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把
HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果
满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类
CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing =
true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
//他已经和SpringBoot的配置文件映射了
private final HttpEncodingProperties properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}

Spring boot整合springMVC

学习链接:https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc

springMVC的自动解管理

  • 中央转发器
  • 控制器
  • 视图解析器
  • 静态资源访问
  • 消息转换器
  • 格式化
  • 静态资源管理

中央转发器:

  xml无需配置:

 <servlet>
<servlet-name>chapter2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup></load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>chapter2</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

  中央转发器被springboot自动接管,不在需要我们在xml文件配置,而且现在的项目也不是web项目,也不存在xml的文件配置。

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\

控制器:

  控制器Controller在springboot的注解扫描范围内自动管理

视图解析器的管理:

  Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    ContentNegotiatingViewResolver:组合所有的视图解析器的;

  使用以前的方式是需要在配置文件中添加配置,现在就不需要配置文件,以前的配置方式:

 <bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value="*.jsp"></property>
</bean>

  在源码:

public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-);
return resolver;
}

  当我们做文件上传的时候我们也会发现multipartResolver是自动被配置好的

  例如在页面上

<form action="/upload" method="post" enctype="multipart/form-data">
<input name="pic" type="file">
<input type="submit">
</form>

  Controller中

 @ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){
String contentType = file.getContentType();
String fileName = file.getOriginalFilename();
/*System.out.println("fileName-->" + fileName);
System.out.println("getContentType-->" + contentType);*/
//String filePath = request.getSession().getServletContext().getRealPath("imgupload/");
String filePath = "D:/imgup";
try {
this.uploadFile(file.getBytes(), filePath, fileName);
} catch (Exception e) {
// TODO: handle exception
} return "success";
} public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
File targetFile = new File(filePath);
if(!targetFile.exists()){
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath+fileName);
out.write(file);
out.flush();
out.close();
}

  其中上传的文件的大小可以通过配置文件的方式配置

 application.properties, 默认限制是10MB,我们可以任意修改

  

消息转换和格式化

  Springboot自动配置了消息转换器

  

  格式化转换器的自动注册

  

  时间类型我们可以在这里修改

  

  在配置文件中指定好时间的模式我们就可以输入了

  

springboot扩展springmvc

  其实springboot并非是完全自动化的,很多跟业务相关的仍然需要我们自己扩展,springboot给我们提供了接口。

  我们可以通过实现WebMvcConfigurer的接口来扩展。

 public interface WebMvcConfigurer {
default void configurePathMatch(PathMatchConfigurer configurer) {
} default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
} default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
} default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
} default void addFormatters(FormatterRegistry registry) {
} default void addInterceptors(InterceptorRegistry registry) {
} default void addResourceHandlers(ResourceHandlerRegistry registry) {
} default void addCorsMappings(CorsRegistry registry) {
} default void addViewControllers(ViewControllerRegistry registry) {
} default void configureViewResolvers(ViewResolverRegistry registry) {
} default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
} default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
} default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
} default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
} default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
} default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
} @Nullable
default Validator getValidator() {
return null;
} @Nullable
default MessageCodesResolver getMessageCodesResolver() {
return null;
}
}

  例如在容器中住注册视图控制器:

  需求:创建一个MyMVCCofnig实现WebMvcConfigurer接口,实现一下addViewControllers方法,我们完成通过/tx访问,转发到success.html的工作

 @Configuration
public class MyMVCCofnig implements WebMvcConfigurer{ @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/tx").setViewName("success");
}

Springboot的数据层开发:

数据源自动管理:

  引入jdbc的依赖和springboot的应用场景

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

  使用yaml的方式配置,配置如下:

 spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/boot_demo
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource

我们可以自己指定数据源配置,通过type来选取使用哪种数据源

# type: org.apache.commons.dbcp2.BasicDataSource

配置druid的数据源

  引入druid的依赖

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.</version>
</dependency>
修改   spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

  在application.yaml中加入

 spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/boot_demo
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize:
minIdle:
maxActive:
maxWait:
timeBetweenEvictionRunsMillis:
minEvictableIdleTimeMillis:
validationQuery: SELECT FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize:
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=

  创建数据源注册类

@Configuration
public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
return new DruidDataSource();
}
}

  配置druid运行期监控

@Configuration
public class DruidConfig { @ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource(){
return new DruidDataSource();
} @Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),
"/druid/*");
Map<String,String> initParams = new HashMap<>();
initParams.put("loginUsername","root");
initParams.put("loginPassword","root");
initParams.put("allow","");//默认就是允许所有访问
initParams.put("deny","192.168.15.21");
bean.setInitParameters(initParams);
return bean;
} //2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean;
bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String,String> initParams = new HashMap<>();
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}

  打开监控页面

 http://localhost:8080/druid

springboot整合jdbctemplate

   创建一个新的项目,同时引入开发的坐标依赖

     <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.</version>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> </dependencies>

在resource的目录下新建一个application.yaml文件,存入你要链接的数据库可相应的配置

 spring:
datasource:
username: root
password: zhanghao22333
url: jdbc:mysql://localhost:3306/boot_demo(注意使用的数据库)
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize:
minIdle:
maxActive:
maxWait:
timeBetweenEvictionRunsMillis:
minEvictableIdleTimeMillis:
validationQuery: SELECT FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize:
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=
mvc:
date-format: yyyy-MM-dd

 可以在Spring-boot-autoconfiguration下的spring:factory中的:

org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\

查看它的源码

@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({JdbcProperties.class})
@Import({JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class})
public class JdbcTemplateAutoConfiguration {
public JdbcTemplateAutoConfiguration() {
}
}

解析:在注解  JdbcTemplateConfiguration.class进去可以看出对jdbcTemplate做的封装,并注意它的主注解@Bean存放到容器中

@ConditionalOnMissingBean({JdbcOperations.class})
class JdbcTemplateConfiguration {
JdbcTemplateConfiguration() {
} @Bean
@Primary
JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
Template template = properties.getTemplate();
jdbcTemplate.setFetchSize(template.getFetchSize());
jdbcTemplate.setMaxRows(template.getMaxRows());
if (template.getQueryTimeout() != null) {
jdbcTemplate.setQueryTimeout((int)template.getQueryTimeout().getSeconds());
} return jdbcTemplate;
}
}

最后在测试使用jdbctemplate查询数据库的操作,在测试中编写

 package zh.stu.springboot.test;

 import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner; import java.util.List;
import java.util.Map; @RunWith(SpringRunner.class)
@SpringBootTest
class TestApplicationTests { @Autowired
JdbcTemplate jdbcTemplate;
@Test
public void contextLoads() {
System.out.println();
List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from tx_person");
System.out.println(maps); } }

最终在控制台输出数据库中的数据

[{pid=, username=张浩, password=, gender=, p_addr=杭州1, birth=--, pname=}, {pid=, username=jj, password=jj, gender=, p_addr=jj, birth=--, pname=jj}]

springboot整合mybatis

导入开发的坐标

 <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.</version>
</dependency>

新建一个实体类,提供get和set的方法

package zh.stu.springboot.test.model;

import java.util.Date;

public class TxPerson {

    private int pid;
private String username;
private String password;
private String pAddr;
private String pname;
private int gender;
private Date birth; public int getPid() {
return pid;
} public void setPid(int pid) {
this.pid = pid;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getpAddr() {
return pAddr;
} public void setpAddr(String pAddr) {
this.pAddr = pAddr;
} public String getPname() {
return pname;
} public void setPname(String pname) {
this.pname = pname;
} public int getGender() {
return gender;
} public void setGender(int gender) {
this.gender = gender;
} public Date getBirth() {
return birth;
} public void setBirth(Date birth) {
this.birth = birth;
} @Override
public String toString() {
return "TxPerson{" +
"pid=" + pid +
", username='" + username + '\'' +
", password='" + password + '\'' +
", pAddr='" + pAddr + '\'' +
", pname='" + pname + '\'' +
", gender=" + gender +
", birth=" + birth +
'}';
}
}

然后新建一个mapper接口

 package zh.stu.springboot.test.mapper;

 import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import zh.stu.springboot.test.model.TxPerson; import java.util.List; /**
* @Mapper:可以给mapper借口自动生成一个实现类,让Spring对mapper接口的bean进行管理,并且可以省略复杂的xml文件的配置
*/
@Mapper
public interface TxPersonMapper {
@Select("select * from tx_person")
public List<TxPerson> selectPersons(); /**
* @Options(useGeneratedKeys = true, keyProperty = "pid")
* 数据库表中的pid是自动增长的,使用@Opetions的注解
* @param p
*/
@Options(useGeneratedKeys = true, keyProperty = "pid")
@Insert("insert into tx_person(pid, username ,password,pname, p_addr, gender, birth)" +
"values(#{pid},#{username},#{password},#{pname},#{pAddr},#{gender},#{birth})")
public void insert(TxPerson p); }

注意:我在数据库中表tx_person的表中的字段p_add的形式存在(中间有一个下划线),而我在生成实体类的时候是:pAddr的形式,所以要添加一个类,将字段更改为驼峰的形式

 package zh.stu.springboot.test;

 import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* 将数据库中的字段下划线更改为大写的方式例如p_add>>pAdd
*/
@Configuration
public class MyBatisConfig { @Bean
public ConfigurationCustomizer getCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
}
};
} }

最后在测试中测试

注入mapper

    @Autowired
TxPersonMapper txPersonMapper;

在方法中对Txperson对象操作

 // 查询
List<TxPerson> txPeople = txPersonMapper.selectPersons();
System.out.println(txPeople);
//新增
TxPerson txPerson=new TxPerson();
txPerson.setBirth(new Date());
txPerson.setGender();
txPerson.setpAddr("洛杉矶");
txPerson.setPassword("");
txPerson.setPname("");
txPerson.setUsername("");
txPersonMapper.insert(txPerson);

  

最新文章

  1. NGUI的localPosition和Position之间的关系
  2. Android之Activity启动模式
  3. hdu 1711Number Sequence
  4. mysql 源码安装
  5. Similarity-based Learning
  6. Linux下centos系统安装redis和php-redis
  7. C#:IO
  8. 【tomcat8】consider increasing the maximum size of the cache
  9. UEP-弹窗给选中数据赋值
  10. 4.2 PCIe体系结构的组成部件
  11. CCF201812-3 CIDR合并
  12. MySQL8.0.15的安装与配置---win10
  13. Envoy 源码分析--event
  14. Oracle数据库基本查询语句
  15. bzoj2049 线段树 + 可撤销并查集
  16. python中对列表和循环使用的小练习
  17. Servlet上传下载
  18. day69
  19. Java Web自定义MVC框架详解 (转)
  20. 【AGC012E】 Camel and Oases ST表+状压dp

热门文章

  1. Ansible 和 Playbook 暂存
  2. ICPC2008哈尔滨-A-Array Without Local Maximums
  3. springcloud feign增加熔断器Hystrix
  4. html根标签设置font-size为100px,使用rem,body没设置字体大小
  5. Stream(Java 8)
  6. Vue学习笔记【14】——自定义指令
  7. Robot Framework:日志输出中文Unicode编码
  8. pandas for python
  9. NOIp2018集训test-10-21 (联考六day1)
  10. (14)centos7 进程管理