SpringBoot笔记

1 SpringBoot概述

1.1 SpringBoot概念

SpringBoot提供了一种快速使用Spring的方式,基于约定大于配置的思想,可以让开发人员不必再配置与逻辑业务之间进行思维的切换,从而大大提高开发速率,一定程度缩短项目周期。

1.2 Spring的缺点

1、配置繁琐
虽然Spring的组件代码是轻量级的,但是它的配置是重量级的。一开始,Spring是用xml配置。Spring2.5引入的基于注解的组件扫描。Spring3.0引入了基于java的配置。
2、依赖繁琐
在环境搭建时,需要分析的要导入哪些库的坐标,而且还要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖版本,随之而来的不兼容问题会严重阻碍项目的开发进度。

1.3 SpringBoot功能

1、自动配置
2、起步依赖
将具备某种功能的坐标打包到一起,并提供一些默认的功能。
3、辅助功能
如嵌入式服务器,安全,指标,健康检测,外部配置等。

SprigBoot并不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式。

2 SpringBoot快速入门

2.1 实现步骤

1、创建一个maven工程
2、导入SpringBoot起步依赖
3、定义Controller等
4、编写引导类(项目入口,启动main方法就可以运行项目)
5、启动测试。

使用Spring Initializer可以快速创建Spring Boot项目

2.2 起步依赖

spring-boot-starter-parent
spring-boot-starter-web

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.6</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本。
在各种starter中,定义了完成该功能需要的总坐标合集,其中大部分版本信息来自于父工程。
我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在版本冲突的问题。

3 SpringBoot配置

SpringBoot是基于约定的,所以很多配置都有默认值,想使用自己的配置可以用application.properties或者application.yml(application.yaml)进行配置。

server.port=8081

yml配置文件

server:
  port: 8082

同一级目录下优先级为:properties>yml>yaml

3.1 yaml

YAML文件的扩展名可以使用.yml或者.yaml。
基本语法:
1、大小写敏感。
2、数据前必须有空格,作为分隔符。
3、使用空格缩进表示层级关系,相同缩进表示同一级。
yaml语法示例:

name: neo
#map集合
person:
  name: ${name}
  age: 20
  address
  	-beijing
  	-shanghai
#行内写法
person2: {name:zhangsan}

#数组
address:
  - beijing
  - shanghai
#行内写法
address2: [beijing,shanghai]
msg1: 'hello \n world'#单引号忽略转义字符
msg2: "hello \n world"#双引号识别转义字符

@Value注解获取值,
Environment获取整个配置

@RestController
public class HelloController {
    @Value("${person.name}")
    private String name;
    @Value("${address[0]}")
    private String address;
    @Autowired
    private Environment env;
    @Autowired
    private Person person;
    @RequestMapping("/hello")
    public String hello(){
        System.out.println(name);
        System.out.println(address);
        System.out.println(env.getProperty("person.name"));
        System.out.println("------------------");
        System.out.println(person);
        return "hello springboot";
    }
}

@ConfigurationProperties注解
javabean

@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private String age;
    private String[] address;
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", address=" + Arrays.toString(address) +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String[] getAddress() {
        return address;
    }
    public void setAddress(String[] address) {
        this.address = address;
    }
}

3.2 profile配置

3.2.1 多profile文件

多个配置文件,每个代表一种环境
application-dev.properties/yml开发环境
application-test.properties/yml测试环境
application-prod.properties/yml生产环境
profile激活方式
1、配置文件:spring.profiles.active=dev
2、虚拟机参数:在VM option指定:-Dspring.profiles.active=dev
3、命令行参数:java -jar xxx.jar --spring.profiles.active=dev

3.2.2 yml多文档方式

在yml中使用 — 来分割不同配置

---
server:
  port: 8080
spring:
  profiles: dev
---
server:
  port: 8081
spring:
  profiles: test
---
server:
  port: 8082
spring:
  profiles: prod

3.2.3 内部配置文件加载顺序

SpringBoot启动后,会从以下位置加载配置文件:
1、file:./config/ 当前项目下的/config目录下
2、file:./ 当前项目的根目录
3、classpath:/config/ classpath的/config目录
4、classpath:/ classpath的根目录
加载顺序为上文的排列顺序,高优先级配置的属性会生效

4 SpringBoot自动配置

4.1 Condition

4.1.1 自定义条件

自定义条件:
1、定义条件类,自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值,matches的两个参数作用如下。
context:上下文对象,可以获取属性值、类加载器、BeanFactory。
metadata:元数据对象,用于获取注解属性
2、判断条件,在初始话Bean时,使用@conditional(条件类.class)注解

@Configuration
public class UserConfig {
    @Bean
    @Conditional(ClassCondition.class)
    public Person user (){
        return new Person();
    }
}
public class ClassCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //1.需求:有引入Jedis则返回true
        //判断redis.clients.jedis.Jedis.class文件是否存在
        boolean flag = true;
        try {
            Class clazz = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }
}

4.1.2 自定义条件注解

我们来自定义一个注解@ConditionOnClass

@Configuration
public class UserConfig {
    @Bean
    //使用自定义注解
    @ConditionOnClass("redis.clients.jedis.Jedis")
    public Person user (){
        return new Person();
    }
}

自定义注解:

@Conditional(ClassCondition2.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConditionOnClass {
    String[] value();
}

自定义条件类:

public class ClassCondition2 implements Condition {

    /**
     *
     * @param context 上下文对象,用于获取环境、IOC容器、ClassLoader对象
     * @param metadata 注解元对象,可以用于获取注解定义的属性值
     * @return
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //2.需求:有引入指定的则返回true
        boolean flag = true;
        try {
            //获取注解属性值vlaue
            Map<String,Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
            String[] values = (String[]) map.get("value");
            for (String className : values) {
                System.out.println("className="+className);
                Class clazz = Class.forName(className);
            }
        } catch (ClassNotFoundException e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }
}

SpringBoot提供的常用条件注解
@ConditionalOnProperty:判断配置文件是否有对应属性和值才初始化Bean;
@ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean;
@ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean。

4.2 内置web服务器切换

默认是tomcat服务器,使用其他服务的的方法:
移除tomcat
在这里插入图片描述

4.3 Enable*注解原理

SpringBoot中提供了很多@Enable开头的注解,这些注解都是用于动态启用某些功能的。其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。
question:SpringBoot工程是否可以直接获取jar包中定义的Bean?
不能。
获取的三种方法示例如下:
方法1、使用@ComponentScan扫描其所在的包。
方法2、可以使用@Import注解,加载类。这些类都会被Spring创建,并放入到IOC容器中。
方法3、可以对Import注解进行封装。

示例如下:

package com.it;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import other.config.EmpConfig;
import other.config.EnableConfig;
/**
 * SpringbootInitApplication引导类所在包:com.it;
 * EmpConfig配置类所在包:other.config;
 * 怎么才能加载到emp的Bean呢
 * 方法1 :使用@ComponentScan 扫描other.config包。@ComponentScan 扫描范围:当前引导类所在包及其子包
 * 方法2 :可以使用@Import注解,加载类。这些类都会被Spring创建,并放入到IOC容器中
 * 方法3 :可以对Import注解进行封装
 */
@SpringBootApplication
//@ComponentScan("other.config")
//@Import(EmpConfig.class)
@EnableConfig
public class SpringbootInitApplication {
	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(SpringbootInitApplication.class, args);
		Object emp = context.getBean("emp");
		System.out.println(emp);
	}
}

配置类

package other.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import other.domain.Emp;
@Configuration
public class EmpConfig {
    @Bean
    public Emp emp(){
        return  new Emp();
    }
}

对Import注解封装

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EmpConfig.class)
public @interface EnableConfig {
}

4.4 Import的四种用法

@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器,而@Import提供4种用法:
用法1、导入Bean
用法2、导入配置类
用法3、导入ImportSelector实现类
用法4、导入ImportBeanDefinitionRegistrar实现类

@SpringBootApplication
/**
 *@Import的四种用法
 * 1、导入Bean
 * 2、导入配置类
 * 3、导入ImportSelector实现类
 * 4、导入ImportBeanDefinitionRegistrar实现类
 */
//@Import(Emp.class)
//@Import(EmpConfig.class)
//@Import(MyImportSelectot.class)
@Import(MyImportBeanDefinitionRegistrar.class)
public class SpringbootInitApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(SpringbootInitApplication.class, args);

		Emp emp = context.getBean(Emp.class);
		System.out.println(emp);
//		Map<String,Emp> empMap= context.getBeansOfType(Emp.class);//获取bean的名称
//		System.out.println(empMap);
	}
}

ImportSelector 的实现类

public class MyImportSelectot implements ImportSelector {
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"other.domain.Emp"};
    }
}

ImportBeanDefinitionRegistrar的实现类

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Emp.class).getBeanDefinition();
        registry.registerBeanDefinition("emp",beanDefinition);
    }
}

4.5 @EnableAutoConfiguration注解

@EnableAutoConfiguration注解内部使用@Import({AutoConfigurationImportSelector.class})来加载配置类。
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化Bean。
并不是所有的Bean都会被初始化,再配置类中使用Condition来加载满足条件的Bean。
在这里插入图片描述
spring.factories里配置了很多需要被加载的类
在这里插入图片描述

4.6 starter

案例:我们自定义redis-starter,当导入redis坐标时,SpringBoot自动创建Jedis的Bean。
实现步骤:
1 创建redis-spring-boot-autoconfigure模块
2 创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure模块
3 在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean。并定义META-INF/spring.factories文件
4 在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作redis。
代码示例如下:
在redis-spring-boot-autoconfigure模块里写一个配置类RedisAutoConfiguration 去加载Bean;

@Configuration
//让RedisProperties被Spring识别
@EnableConfigurationProperties(RedisProperties.class)
//保证Jedis在的时候才加载这个bean
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {
    /**
     * 提供Jedis的bean
     * 从RedisProperties里动态获取ip跟端口
     */
    @Bean
    //如果没有一个名称叫jedis的bean时,才去创建这样一个Bean
    @ConditionalOnMissingBean(name = "jedis")
    public Jedis jedis( RedisProperties redisProperties){
        System.out.println("创建了jedis的bean......");
        return new Jedis(redisProperties.getHost(),redisProperties.getPort());
    }
}

可以从配置文件里获取redis的配置,默认为本地,端口为6379;

//加载以redis开头的配置
@ConfigurationProperties(prefix = "redis")
public class RedisProperties {
    private String host="localhost";
    private int port=6379;
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
}

新增META-INF/spring.factories文件,为啥要创建这个文件,参考4.5@EnableAutoConfiguration注解的作用。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.itxwz.RedisAutoConfiguration

在redis-spring-boot-starter模块引入依赖

<dependency>
	<groupId>com.itxwz</groupId>
	<artifactId>redis-spring-boot-configuration</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

在测试模块springboot-init里引入redis-spring-boot-starter

<!--引入自定义的redis的starter-->
<dependency>
	<groupId>com.itxwz</groupId>
	<artifactId>redis-spring-boot-starter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

在测试模块里看能否获取到jedis的Bean

@SpringBootApplication
public class SpringbootInitApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(SpringbootInitApplication.class, args);
		Jedis jedis = context.getBean(Jedis.class);
		System.out.println(jedis);
		jedis.set("name","itcast");
		String name = jedis.get("name");
		System.out.println(name);

	}
	//在这里创建一个Jedis的bean,看RedisAutoConfiguration还会创建Jedis的bean嘛(不会再创建了)
	@Bean
	public Jedis jedis(){
		return new Jedis("localhost",6379);
	}
}

可以在测试模块的配置文件里配置redis的地址跟端口

redis.host=localhost
redis.port=6379

至此,自定义的redis-starter结束。
springBoot的自动装配里其实已经写好了,如下:
在这里插入图片描述

5 SpringBoot事件监听

SpringBoot的佳通机制,其实时对Java提供的时间监听机制的封装。

5.1 java监听机制

java中的事件监听机制定义了以下几个角色:
事件:Event,继承java.util.EventObject类的对象
事件源:Source,任意对象Object
监听器:Listener,实现java.util.EventListener接口的对象

5.2 SpringBoot监听机制

SpringBoot在项目启动时,会对几个监听器进行回调,我们可以实现这些监听器接口,在醒目启动时完成一些操作。
ApplicationContextInitializer、SpringApplicationRunListener、CommandLineRunner、ApplicationRunner
实现ApplicationRunner接口,如下:

/**
 * 当项目启动后执行run方法,用处:比如缓存预热,加数据库的数据加载到缓存
 */
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        System.out.println("ApplicationRunner...run");
        System.out.println(Arrays.asList(applicationArguments.getSourceArgs()));
    }
}

实现ApplicationRunner接口,如下:

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... strings) throws Exception {
        System.out.println("CommandLineRunner...run");
        System.out.println(Arrays.asList(strings));
    }
}

实现ApplicationContextInitializer接口,如下:

@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer...");
    }
}

配置META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=com.it.listener.MyApplicationContextInitializer

实现SpringApplicationRunListener 接口,如下:

//@Component
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
    public MySpringApplicationRunListener(SpringApplication springApplication,String[] args) {
    }
    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("starting...项目启动中");
    }
    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("environmentPrepared");
    }
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("contextPrepared...环境对象开始准备");
    }
    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("contextLoaded...上下文对象开始加载");
    }
    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("started...上下文对象加载完成");
    }
    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("running...项目启动完成,开始运行");
    }
    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("failed...项目启动失败");
    }
}

配置META-INF/spring.factories

org.springframework.boot.SpringApplicationRunListener=com.it.listener.MySpringApplicationRunListener

6 SpringBoot监控

6.1 actuator的基本使用

springboot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况,Bean的加载情况、配置属性、日志信息等
那么使用方法也很简单,加上如下坐标,访问http://localhost:8080/actuator即可

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

可以配置查看完整的健康信息

#开启将抗检查的完整信息
management.endpoint.health.show-details=always

在这里插入图片描述

6.2 SpringBoot-admin图形化界面使用

示例如下:
快速创建springboot-admin-server模块,选择java Web,Ops下的Spring boot Admin(Server)
在这里插入图片描述
模块创建好可以看到下面这个依赖:

<dependency>
	<groupId>de.codecentric</groupId>
	<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>

在引导类开启admin-server

//开启admin-server
@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringbootAdminServerApplication.class, args);
	}
}

在application.properties里配置server的端口

server.port=9000

server创建完成,下面来创建springboot-admin-client模块,选择java Web,Ops下的Spring boot Admin(Client)

<dependency>
	<groupId>de.codecentric</groupId>
	<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>

配置application.properties文件,如下

#执行admin.server地址
spring.boot.admin.client.url=http://localhost:9000
management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*

admin-server配置了9000的端口,我们呢直接访问http://localhost:9000
server里提供了很多功能,例如,可以看到线程实时状态:
在这里插入图片描述

7 SpringBoot的部署

SpringBoot项目开发完成后,支持2种方式部署到服务器:
1、jar包(官方推荐)
2、war包
下面介绍下war包的打包方式。
pom.xml文件里定义打包方式:

	<groupId>com.id</groupId>
	<artifactId>springboot-deploy</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-deploy</name>
	<description>Demo project for Spring Boot</description>
	<packaging>war</packaging>

引导类继承SpringBootServletInitializer,重写configure方法

@SpringBootApplication
public class SpringbootDeployApplication extends SpringBootServletInitializer{
	public static void main(String[] args) {
		SpringApplication.run(SpringbootDeployApplication.class, args);
	}
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		return builder.sources(SpringbootDeployApplication.class);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans Spring-Context Spring-Context-Support Spring-Expression AOP Spring-AOP Spring-Aspects Messaging Spring-Messaging WEB Spring-Web Spring-Webmvc Spring-WebSocket Spring-Webmvc-Portlet 数据访问/集成(DataAccess/Intefration) Spring-JDBC Spring-TX Spring-ORM Spring-OXM Spring-JMS Spring的生态 Spring Boot Spring XD Spring Cloud Spring Data Spring Integration Spring Batch Spring Security Spring HATEOAS Spring Social Spring AMQP Spring Mobile Spring for Android Spring Web Flow Spring Web Services Spring LDAP Spring Session Spring项目快速搭建 Maven简介 Maven安装 Maven的pom.xml dependencies dependency 变量定义 编译插件 Spring项目的搭建 Spring Tool Suite https://spring.io/tools/sts/all IntelliJ IDEA NetBeans https://netbeans.org/downloads/ Spring基础配置 依赖注入 声明Bean的注解 @Component组件,没有明确的角色 @Service在业务逻辑层(service层) @Repository在数据访问层(dao层) @Controller在展现层(MVC→SpringMVC) 注入Bean的注解 @Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个Bean AOP @Aspect 声明是一个切面 拦截规则@After @Before @Around PointCut JoinPoint Spring常用配置 Bean的Scope Singleton Prototype Request Session GlobalSession SpringEL和资源调用 注入普通字符 注入操作系统属性 注入表达式云算结果 注入其他Bean的属性 注入文件内容 注入网址内容 注入属性文件 Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,集成ApplicationEvent 定义事件监听器,实现ApplicationListener 使用容器发布事件 Spring高级话题 Spring Aware BeanNameAware BeanFactoryAware

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值