day11【过渡】SpringBoot

day11【过渡】SpringBoot

1、HelloWorld(Maven版本)

1.1、创建Maven工程

  • 新建Maven工程

image-20200620194312770

image-20200620194336165

  • 因为SpringBoot自带嵌入式Tomcat服务器,我们打包为jar包即可

image-20200620194429738

1.2、导入依赖

  • pom文件中导入如下依赖
<!-- 继承SpringBoot官方指定的父工程 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
</parent>

<dependencies>
    <!-- 加入Web开发所需要的场景启动器 -->
    <dependency>
        <!-- 指定groupId和artifactId即可,版本已在父工程中定义 -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<!-- Maven构建过程相关配置 -->
<build>
    <!-- 构建过程中所需要用到的插件 -->
    <plugins>
        <!-- 这个插件将SpringBoot应用打包成一个可执行的jar包 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

1.3、创建主启动类

  • 创建SpringBoot的主启动类

image-20200620195155255

// 将当前类标记为一个SpringBoot应用
@SpringBootApplication
public class SpringBootMainType {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootMainType.class, args);
    }

}

1.4、创建Handler

  • 创建Handler组件,代码用于测试

image-20200620195246775

@RestController
public class HelloHandler {

    @RequestMapping("/get/spring/boot/hello/message")
    public String getMessage() {
        return "first blood!!!☆☆☆";
    }

}

1.5、运行程序

  • 运行SpringBoot应用程序

image-20200620195414374

  • 访问页面:http://localhost:8080/get/spring/boot/hello/message

image-20200620195602811

2、HelloWorld(Starter版本)

2.1、创建SpringBoot工程

  • 使用Spring Starter创建SpringBoot工程

image-20200620201129751

image-20200620201302453

  • 引入Spring Web

image-20200620201335939

2.2、工程结构

  • 工程结构如下

image-20200620201815183

2.3、创建Handler

  • 创建Handler组件,用于测试

image-20200620202339788

@RestController
public class HelloHandler {
	
	@RequestMapping("/hello")
	public String hello() {
		return "Hello from Heygo~";
	}

}

2.4、运行程序

  • 访问页面:http://localhost:8080/hello

image-20200620202606415

3、Maven插件的作用

3.1、不使用Maven插件

  • 注释掉Maven插件的依赖

image-20200620203715033

  • Maven CleanMaven Install拳法打一套,生成jar

image-20200620203517358

  • 手动运行生成的jar

image-20200620203620011

3.2、使用Maven插件

  • 重新引入Maven插件的依赖

image-20200620204342883

  • Maven CleanMaven Install拳法打一套,生成jar

image-20200620204320637

  • 手动运行生成的jar

image-20200620204509850

4、HelloWorld解读

4.1、包扫描方式

4.1.1、按照约定
  • SpringBoot环境下,主启动类所在包、主启动类所在包的子包,都会被自动扫描。

image-20200620213009912

4.1.2、手动指定
  • 在主启动类上使用@ComponentScan注解,指定扫描的包,但是此时约定规则会失效。
@SpringBootApplication
@ComponentScan("com.atguigu.spring.boot.other.handler")
public class SpringBootSpringProjectApplication{
    
    public static void main(Stringll args){
    	SpringApplication. run(SpringBootSpringProjectApplication. class, args);
	}
    
}

4.2、父工程

  • 我们工程依赖于spring-boot-starter-parent

image-20200620214227587

  • spring-boot-starter-parent工程依赖于spring-boot-dependencies

image-20200620214304336

  • spring-boot-dependencies工程中包含了诸多的dependency

image-20200620214422905

5、properties配置文件

5.1、文件位置与名称

  • properties配置文件必须位于resources文件夹下,名称必须为application.properties

image-20200620215145457

5.2、properties文件编码

5.2.1、新建的编码格式
  • 设置新建properties文件时,使用的编码格式

image-20200620215631909

5.2.2、显示的编码格式
  • 右击properties文件,选择Properties

image-20200620220042537

  • 将其编码设置为UTF-8

image-20200620220116836

  • 一套打完,搞定~

image-20200620220628393

5.3、修改默认配置

# 配置端口号
server.port=8888				

# 配置工程路径名		
server.servlet.context-path=/Heygo

5.4、测试

  • 乌拉~

image-20200620220529062

6、yml配置文件

6.1、创建yml配置文件

  • Create New File

image-20200621094059352

6.2、yml编辑器

  • 打开yml文件报错
Plug-in "org.springframework.ide.eclipse.boot.properties.editor.yaml" was unable to instantiate class "org.springframework.ide.eclipse.boot.properties.editor.yaml.SpringYamlEditor".
  • 通过Eclipse Marketplace重新安装了一下Spring tool ,重启后就好了。

image-20200621095052939

6.3、yml使用示例

server:
  port: 8888
  servlet:
    context-path: /Heygo

6.4、读取yml配置文件

6.4.1、创建实体类

image-20200621104125589

  • Student
// 当前类存放读取yml配置文件的数据,要求当前类也在IOC容器中
@Component

// @ConfigurationProperties表示和yml配置文件对应,读取其中数据
// prefix属性表示和yml配置文件中以“student”开头的配置项对应
@ConfigurationProperties(prefix = "student")
public class Student {
	
	private Integer stuId;
	private String stuName;
	private Boolean graduated;
	private String[] subject;
	
	// 如果不使用@DateTimeFormat指定日期时间格式,那么必须使用默认格式“1990/10/12”
	// 如果不使用默认格式就必须使用@DateTimeFormat注解的pattern指定日期时间格式
	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private Date birthday;
	private Map<String, String> teachers;
	private Address address;
	
	public Student() {
		
	}

	public Student(Integer stuId, String stuName, Boolean graduated, String[] subject, Date birthday,
			Map<String, String> teachers, Address address) {
		super();
		this.stuId = stuId;
		this.stuName = stuName;
		this.graduated = graduated;
		this.subject = subject;
		this.birthday = birthday;
		this.teachers = teachers;
		this.address = address;
	}

	@Override
	public String toString() {
		return "Student [stuId=" + stuId + ", stuName=" + stuName + ", graduated=" + graduated + ", subject="
				+ Arrays.toString(subject) + ", birthday=" + birthday + ", teachers=" + teachers + ", address="
				+ address + "]";
	}

	public Integer getStuId() {
		return stuId;
	}

	public void setStuId(Integer stuId) {
		this.stuId = stuId;
	}

	public String getStuName() {
		return stuName;
	}

	public void setStuName(String stuName) {
		this.stuName = stuName;
	}

	public Boolean getGraduated() {
		return graduated;
	}

	public void setGraduated(Boolean graduated) {
		this.graduated = graduated;
	}

	public String[] getSubject() {
		return subject;
	}

	public void setSubject(String[] subject) {
		this.subject = subject;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Map<String, String> getTeachers() {
		return teachers;
	}

	public void setTeachers(Map<String, String> teachers) {
		this.teachers = teachers;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
	
}
  • Address类
public class Address {

	private String province;
	private String city;
	private String street;

	public Address() {
		
	}

	@Override
	public String toString() {
		return "Address [province=" + province + ", city=" + city + ", street=" + street + "]";
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getStreet() {
		return street;
	}

	public void setStreet(String street) {
		this.street = street;
	}

}
6.4.2、编写yml配置文件
  • 编写application.yml配置文件

image-20200621104328832

student:
  stu-id: 5
  stu-name: jerry
  graduated: false
  subject:
  - java
  - php
  - mysql
  birthday: 1998-10-12 20:15:06
  teachers:
    java: tom
    mysql: tony
    web: bob
  address:
    province: 广东
    city: 深圳
    street: 宝安大道
atguigu.best.wishes: "圣诞快乐!"
6.4.3、测试
  • 测试代码

image-20200621104602670

@SpringBootTest
class SpringBootAutoProjectApplicationTests {

	@Autowired
	private Student student;
	
	Logger logger = LoggerFactory.getLogger(SpringBootAutoProjectApplicationTests.class);
	
	@Value("${atguigu.best.wishes}")
	private String wishes;
	
	@Test
	void contextLoads() {
	
		logger.info(student.toString());
		logger.info(wishes);
		
	}

}
  • 程序运行输出结果
2020-06-21 10:48:49.819  INFO 1264 --- [           main] .b.SpringBootAutoProjectApplicationTests : Student [stuId=5, stuName=jerry, graduated=false, subject=[java, php, mysql], birthday=Mon Oct 12 20:15:06 GMT+08:00 1998, teachers={java=tom, mysql=tony, web=bob}, address=Address [province=广东, city=深圳, street=宝安大道]]
2020-06-21 10:48:49.819  INFO 1264 --- [           main] .b.SpringBootAutoProjectApplicationTests : 圣诞快乐!

6.5、日志配置

  • root日志级别
#非常不建议使用root给SpringBoot设置全局范围的日志级别,影响范围太大。没有特殊需要还是保持默认级别INFO
logging:
  level:
    root: debug
  • 局部日志级别
#如果局部代码由需要设置日志级别,那么使用“包名加级别”方式局部指定
logging:
  level:
    com.atguigu.spring.boot.test: debug

7、SpringBoot相关注解

7.1、@Configuration

  • 使用@Configuration注解标记一个类后,这个类成为配置类,加载这个类中的配置可以取代以前的XML配置文件。
@Configuration
public class SpringAnnotationConfig{
  • 基于注解类而不是XML配置文件创建IOC容器对象的代码如下:
ApplicationContext iocContainer =new AnnotationConfigApplicationContext(SpringAnnotationConfig.class);

7.2、@Bean

  • IOC容器中添加Bean
@Configuration
public class SpringAnnotationConfig{
    
    @Bean
    public EmployeeService getEmployeeService(){
    	return new EmployeeService();
    }
    
}

7.3、@Import

  • 相对于@Bean注解,使用@Import注解可以更便捷的将一个类加入IOC容器。
@Configuration
@Import(EmployeeHandler.class)
public class SpringAnnotationConfig{

7.4、@Conditional

  • 一个类在满足特定条件时才将其IOC容器。

image-20200621111131292

7.5、ComponentScan

  • 指定IOC容器扫描的包。相当于在XML中配置context:component-scan
@ComponentScan(
	value="com.atguigu.spring.annotation.component",
    useDefaultFilters=false, 
    includeFilters={
		@Filter(type=FilterType.ANNOTATION, classes=Controller.class)
	excludeFilters={
		@Filter(type=FilterType.ANNOTATION, classes=Service.class)
	}

7.6、@SpringBootApplication

  • @SpringBootApplication注解:
    • @SpringBootConfiguration:标记该类是一个配置类
    • @EnableAutoConfiguration:启用自动配置
    • @ComponentScan:包扫描
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
  • @SpringBootConfiguration注解:其实就是个@Configuration注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
  • @EnableAutoConfiguration注解:启用自动配置

  • SpringBoot在这里通过@lmport注解中的AutoConfigurationlmportSelector.class将所有需要导入的组件以全类名的方式返回;

  • 这些组件就会被添加到容器中,给容器中导入非常多的自动配置类(XxxxAutoConfiguration)

    • 这样就给容器中导入了这个场景需要的所有组件,并配置好这些组件。而这些组件以前是需要我们手动在XML中配置才能加入IOC容器。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
  • @AutoConfigurationPackage注解:

    SpringBoot在这里通过@lmport注解中的AutoConfigurationPackages.Registrar.class将主启动类所在包和它的子包中的所有组件扫描到IOC容器。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
  • AutoConfigurationPackages.Registrar负责自动包扫描

image-20200621112246660

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
    }

    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImports(metadata));
    }

}

8、SpringBoot基本原理

8.1、读取spring.factories配置文件

  • SpringBoot启动时会读取

    • spring-boot-autoconfigure包下META-INF文件夹下的spring.factories文件。

    • 读取org.springframework.boot.autoconfigure.EnableAutoConfiguration属性的值加载自动配置类。

image-20200621145310039

image-20200621145327091

  • spring.factories配置文件中:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration项包含了诸多的自动配置类

image-20200621150318151

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

8.2、加载XxxProperties配置类

  • 根据自动配置类中指定的XxxProperties类设置自动配置的属性值,开发者也可以根据XxxProperties类中指定的属性在yml配置文件中修改自动配置。即要么使用默认值,要么通过yml配置文件修改默认值。

  • RedisAutoConfiguration为例:Redis的默认配置在RedisProperties配置类

image-20200621151850111

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}
  • RedisProperties配置类:在application.yml中,前缀为spring.redis
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

	/**
	 * Database index used by the connection factory.
	 */
	private int database = 0;

	/**
	 * Connection URL. Overrides host, port, and password. User is ignored. Example:
	 * redis://user:password@example.com:6379
	 */
	private String url;

	/**
	 * Redis server host.
	 */
	private String host = "localhost";

	/**
	 * Login password of the redis server.
	 */
	private String password;

	/**
	 * Redis server port.
	 */
	private int port = 6379;

	/**
	 * Whether to enable SSL support.
	 */
	private boolean ssl;

	/**
	 * Connection timeout.
	 */
	private Duration timeout;

	private Sentinel sentinel;

	private Cluster cluster;

	private final Jedis jedis = new Jedis();

	private final Lettuce lettuce = new Lettuce();

	public int getDatabase() {
		return this.database;
	}

	public void setDatabase(int database) {
		this.database = database;
	}

	public String getUrl() {
		return this.url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getHost() {
		return this.host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getPort() {
		return this.port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public boolean isSsl() {
		return this.ssl;
	}

	public void setSsl(boolean ssl) {
		this.ssl = ssl;
	}

	public void setTimeout(Duration timeout) {
		this.timeout = timeout;
	}

	public Duration getTimeout() {
		return this.timeout;
	}

	public Sentinel getSentinel() {
		return this.sentinel;
	}

	public void setSentinel(Sentinel sentinel) {
		this.sentinel = sentinel;
	}

	public Cluster getCluster() {
		return this.cluster;
	}

	public void setCluster(Cluster cluster) {
		this.cluster = cluster;
	}

	public Jedis getJedis() {
		return this.jedis;
	}

	public Lettuce getLettuce() {
		return this.lettuce;
	}
    
    //....

8.3、@ConditionalXxx注解

  • 根据@ConditionalXxx注解决定加载哪些组件。SpringBoot通过@ConditionalXxx注解指定特定组件加入IOC容器时所需要具备的特定条件。这个组件会在满足条件时加入IOC容器。

9、SpringBoot整合Mybatis

9.1、引入Mybatis依赖

  • pom文件中引入Mybatis所需的依赖
<!-- SpringBoot整合Mybatis所需依赖 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid数据源 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.5</version>
</dependency>
<!-- spring-boot test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

9.2、建库建表

  • 建表并插入数据

image-20200621155443578

CREATE TABLE `springboot`.`table_emp` (
  `emp_id` INT (11) NOT NULL AUTO_INCREMENT,
  `emp_name` VARCHAR (32),
  `emp_age` INT (11),
  PRIMARY KEY (`emp_id`)
) ;

9.3、创建实体类

  • 创建Emp实体类

image-20200621155022382

public class Emp {
	
	private Integer empId;
	private String empName;
	private Integer empAge;
	
	public Emp() {
		
	}

	public Emp(Integer empId, String empName, Integer empAge) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empAge = empAge;
	}

	@Override
	public String toString() {
		return "Emp [empId=" + empId + ", empName=" + empName + ", empAge=" + empAge + "]";
	}

	public Integer getEmpId() {
		return empId;
	}

	public void setEmpId(Integer empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public Integer getEmpAge() {
		return empAge;
	}

	public void setEmpAge(Integer empAge) {
		this.empAge = empAge;
	}

}

9.4、创建Mapper层

  • Mapper接口

image-20200621155616729

public interface EmpMapper {
	
	List<Emp> selectAll();

}
  • Mapper映射文件

image-20200621155215048

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spring.boot.mapper.EmpMapper">
	<select id="selectAll"
		resultType="com.atguigu.spring.boot.entity.Emp">
		select emp_id empId, emp_name empName, emp_age empAge
		from
		table_emp
	</select>
</mapper>

9.5、yml配置文件

  • 配置数据源datasource
  • 指定Mapper映射文件所在位置
  • 修改局部日志级别

image-20200621155711337

spring:
  datasource:
    name: mydb
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath*:/mybatis/mapper/*Mapper.xml
logging:
  level:
    com.atguigu.spring.boot.mapper: debug
    com.atguigu.spring.boot.test: debug

9.6、DataSourceProperties

  • 回顾一波XxxProperties
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {

	private ClassLoader classLoader;

	/**
	 * Name of the datasource. Default to "testdb" when using an embedded database.
	 */
	private String name;

	/**
	 * Whether to generate a random datasource name.
	 */
	private boolean generateUniqueName = true;

	/**
	 * Fully qualified name of the connection pool implementation to use. By default, it
	 * is auto-detected from the classpath.
	 */
	private Class<? extends DataSource> type;

	/**
	 * Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
	 */
	private String driverClassName;

	/**
	 * JDBC URL of the database.
	 */
	private String url;

	/**
	 * Login username of the database.
	 */
	private String username;

	/**
	 * Login password of the database.
	 */
	private String password;

	/**
	 * JNDI location of the datasource. Class, url, username and password are ignored when
	 * set.
	 */
	private String jndiName;

	/**
	 * Initialize the datasource with available DDL and DML scripts.
	 */
	private DataSourceInitializationMode initializationMode = DataSourceInitializationMode.EMBEDDED;

	/**
	 * Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or
	 * data-${platform}.sql).
	 */
	private String platform = "all";

	/**
	 * Schema (DDL) script resource references.
	 */
	private List<String> schema;

	/**
	 * Username of the database to execute DDL scripts (if different).
	 */
	private String schemaUsername;

	/**
	 * Password of the database to execute DDL scripts (if different).
	 */
	private String schemaPassword;

	/**
	 * Data (DML) script resource references.
	 */
	private List<String> data;

	/**
	 * Username of the database to execute DML scripts (if different).
	 */
	private String dataUsername;

	/**
	 * Password of the database to execute DML scripts (if different).
	 */
	private String dataPassword;

	/**
	 * Whether to stop if an error occurs while initializing the database.
	 */
	private boolean continueOnError = false;

	/**
	 * Statement separator in SQL initialization scripts.
	 */
	private String separator = ";";

	/**
	 * SQL scripts encoding.
	 */
	private Charset sqlScriptEncoding;
    
    //...

9.7、MapperScan

  • 在主启动类上配置MapperScan
@MapperScan("com.atguigu.spring.boot.mapper")
@SpringBootApplication
public class SpringBootAutoProjectApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootAutoProjectApplication.class, args);
	}

}

9.8、测试

  • 创建测试类

image-20200621160443768

@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisTest {
	
	@Autowired
	private EmpMapper empMapper;
	
	private Logger logger = LoggerFactory.getLogger(MybatisTest.class);
	
	@Test
	public void testMapper() {
		List<Emp> list = empMapper.selectAll();
		for (Emp emp : list) {
			logger.debug(emp.toString());
		}
	}

}
  • 程序运行输出结果
2020-06-21 16:03:35.874  INFO 16324 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2020-06-21 16:03:35.994 DEBUG 16324 --- [           main] c.a.s.boot.mapper.EmpMapper.selectAll    : ==>  Preparing: select emp_id empId, emp_name empName, emp_age empAge from table_emp 
2020-06-21 16:03:36.012 DEBUG 16324 --- [           main] c.a.s.boot.mapper.EmpMapper.selectAll    : ==> Parameters: 
2020-06-21 16:03:36.032 DEBUG 16324 --- [           main] c.a.s.boot.mapper.EmpMapper.selectAll    : <==      Total: 2
2020-06-21 16:03:36.033 DEBUG 16324 --- [           main] c.atguigu.spring.boot.test.MybatisTest   : Emp [empId=1, empName=Heygo, empAge=24]
2020-06-21 16:03:36.033 DEBUG 16324 --- [           main] c.atguigu.spring.boot.test.MybatisTest   : Emp [empId=2, empName=Oneby, empAge=24]
2020-06-21 16:03:36.050  INFO 16324 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

10、SpringBoot整合Redis

10.1、CentOS下安装Redis

  • 参考周阳老师Redis课件

10.2、启动Redis

10.2.1、修改配置文件
  • 关闭保护模式

image-20200621213908955

  • 后台运行

image-20200621213919919

  • 绑定至本机IP地址

image-20200621213939225

10.2.2、使用自定义配置启动Redis
  • 启动Redis服务器

image-20200621214024686

  • 使用redis-cli客户端工具,连接至Redis服务器

image-20200621214113240

10.3、Windows无法连接虚拟机的Redis

10.3.1、问题描述
  • Windows中,无法连接虚拟机的Redis服务器
10.3.2、 关闭防火墙
  • 关闭防火墙就行了。。。

image-20200621214352794

service iptables stop

10.4、导入Starter

  • 导入spring-boot-starter-data-redis
<!-- SpringBoot整合Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

10.5、yml配置文件

  • 配置Redis主机地址以及日志级别
spring:
  redis:
    host: 192.168.152.129
logging:
  level:
    com.atguigu.spring.boot.test: debug

10.6、测试

  • 测试代码:String
@Autowired
private StringRedisTemplate stringRedisTemplate;

private Logger logger = LoggerFactory.getLogger(RedisTest.class);

@Test
public void testStringRedisTemplate() {

    // 获取ValueOperations对象
    ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

    // 准备数据
    String key = "Hello";
    String value = "Hi";

    // 存入数据
    operations.set(key, value);

    // 读取数据
    String readValue = operations.get(key);

    // 输出
    logger.debug(readValue);
}
  • 程序运行结果

image-20200621214903369

2020-06-21 21:45:51.152 DEBUG 23840 --- [           main] com.atguigu.spring.boot.test.RedisTest   : Hi
  • 测试代码:List
@Autowired
private StringRedisTemplate stringRedisTemplate;

private Logger logger = LoggerFactory.getLogger(RedisTest.class);

@Test
public void testStringRedisTemplateForList() {

    // 获取ValueOperations对象
    ListOperations<String, String> operations = stringRedisTemplate.opsForList();

    // 准备数据
    String key = "fruit";
    List<String> values = new ArrayList<String>();
    values.add("apple");
    values.add("orange");
    values.add("banana");

    // 存入数据
    operations.leftPushAll(key, values);

    // 读取数据
    List<String> readValues = operations.range(key, 0, -1);

    // 输出
    logger.debug(readValues.toString());
}
  • 程序运行结果

image-20200621220041994

2020-06-21 21:58:50.406 DEBUG 4452 --- [           main] com.atguigu.spring.boot.test.RedisTest   : [banana, orange, apple]

10.7、Redis自动化配置

  • 为什么我们能直接直接注入StringRedisTemplate?人家自动配置直接给我们@Bean放在IOC容器中了
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}
  • 为什么我们不用配置端口号?自动配置的功劳~

image-20200621221016493

  • 导入了两个连接池工具LettuceConnectionConfigurationdisConnectionConfiguration,究竟用哪个?可以看源码进一步分析~

image-20200621221206748

11、SpringBoot整合Thymeleaf

11.1、导入依赖

  • 导入Thymeleaf的依赖
<!-- SpringBoot整合ThymeLeaf -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

11.2、编写Handler

  • 编写Handler代码:直接转发至模板页面

image-20200621231434827

@RestController
public class HelloHandler {
	
	@RequestMapping("/hello/thymeleaf")
	public String helloTthymeleaf() {
		return "hello-thymeleaf";
	}

}

11.3、创建模板

  • Templates文件夹面创建模板

image-20200621231542880

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<p th:text="Hello from Thymeleaf">Hello from html page</p>
</body>
</html>

11.4、实验效果

  • 直接访问本地文件

image-20200621231319316

  • 通过Web访问

image-20200621231312590

12、Thymeleaf语法

12.1、名称空间

使用Thymeleaf时我们直接创建HTML文件即可,只是需要在html标签中加入Thymeleaf的名称空间。

<!--加入名称空间-->
<html xmlns:th="http://www.thymeleaf.org">

12.2、修改标签文本值

<h3>替换标签体</h3>
<p th:text=“新值”>原始值</p>

12.3、修改指定属性值

<h3>替换属性值</h3>
<input value="old-value" th:value="new-value"/>

12.4、表达式中访问属性域

<h3>访问请求域</h3>
<p th:text="${reqAttrName}">aaa</p><p th:text="${#httpServletRequest.getAttribute('reqAttrName')}">这里注意给属性名加引号</p>

<h3>访问Session域</h3>
<p th:text="${session.ssAttrName}">bbb</p>
<h3>访问Application域</h3>
<p th:text="${application.appAttrName}">ccc</p>

12.5、解析URL地址

<h3>解析URL地址</h3>
<p th:text="@{/aaa/bbb/ccc}">页面上看到的是:/contextPath/aaa/bbb/ccc</p>

12.6、直接执行表达式

<h3>直接执行表达式</h3>
<p>有转义效果:[[${reqAttrName}]]</p><p>无转义效果:[(${reqAttrName})]</p>

12.7、分支与迭代

12.7.1、条件判断
<h3>测试if判断</h3>
<p th:if="${not #strings.isEmpty(reqAttrName)}">if判断为真时输出的内容</p>
~<p th:if="${#strings.isEmpty(reqAttrName)}">if判断为真时输出的内容</p>~
12.7.2、遍历集合
<h3>测试循环</h3>
<!-- 使用th:each进行集合数据迭代 -->
<!-- th:each="声明变量:${集合}" -->
<!-- th:each用在哪个标签上,哪个标签就会出现多次 -->
<div>
    <p th:text="${card}" th:each="card:${cradList}">
</div>

12.8、包含其他代码片段

12.8.1、声明代码片段
<div th:fragment="commonPart">
    <p>内部内容</p>
</div>
12.8.2、包含
  • xxx部分是访问模板文件时的逻辑视图名称,要求这个xxx拼接yml里配置前后缀之后得到访问模板文件的物理视图。
  • 比如:想包含templates/include/aaa.html页面,那么xxx就是include/aaa,因为templates是前缀,.html是后缀
表达式作用
th:insert="~{xxx::zzz}"以插入方式引入(使用代码片段整体插入当前标签内)
th:replace="~{xxx::zzz}"以替换方式引入(使用代码片段整体替换当前标签内)
th:include="~{xxx::zzz}"以包含方式引入(使用代码片段整体包含到当前标签内)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值