SpringBoot学习

一、springBoot入门

springBoot Hello world
1、创建一个maven工程
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.5.2</version>

    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
2、写一个启动类
@SpringBootApplication
public class HelloSpringBoot {

    public static void main(String[] args) {
        SpringApplication.run(HelloSpringBoot.class, args);
    }
}
3、写一个controller
@Controller
public class Hello {

    @RequestMapping("/hello")
    @ResponseBody
    public String hello() {

        return "hello world";
    }
}
4、简化部署
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.2</version>
            </plugin>
        </plugins>
这个插件可以将这个应用打成jar包直接使用java -jar执行

5、hello world 探究

从这个启动类注解开始
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
1、@SpringBootApplication头上的@SpringBootConfiguration
	标注在类上面表示为springboot的配置类
	他也属于spring中的@Configuration也是一个组件
2、@SpringBootApplication头上的@EnableAutoConfiguration
	告诉springboot帮我们自动配置,开启自动配置
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {}
1、@EnableAutoConfiguration头上的@AutoConfigurationPackage
	会导入一个AutoConfigurationPackages.Registrar.class组件;这个组件会将配置类(标有			@SpringBootApplication)的所在的包及其子包里面的所有组件扫描到spring容器中
2、@EnableAutoConfiguration头上的@Import(AutoConfigurationImportSelector.class)
	会帮我们导入一个AutoConfigurationImportSelector组件,这个组件的作用是,将所有需要导入的组件全类名返回;这些组件会被添加到容器中,会给容器中添加好多自动类配置类(XXXConfiguration),就是给容器中导入这个场景所需要的一些组件

例如:

在这里插入图片描述

springboot怎么找到的这些自动配置类呢?

用这段代码找List<String> configurations = SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class;,
				getBeanClassLoader());
springboot在启动时候会从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration.class的值,将这些值作为自动配置类导入到容器中,各个框架的自动配置类就生效了,帮我们进行自动配置工作

二、配置文件

1、@ConfigurationProperties用法
@ConfigurationProperties(prefix = "配置文件中的属性前缀")//默认从全局配置文件中获取值
@Component
public class User {
    private String name;
    private String password;
    private int id;
	get  set
}

我们还可以使用@EnableConfigurationPropertiesUser.class)这个注解来注册User这个配置绑定,这样的user配置绑定类就不需要写@Component了;@EnableConfigurationProperties这个会将user导入到容器中
2、@Value和@ConfigurationProperties区别
@ConfigurationProperties@Value
功能批量导入配置文件中的属性一个个的指定
松散语法支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
3、@PropertySource()和@ImportResource()
@PropertySource()可以加载指定的配置文件
@ImportResource()导入spring配置文件,让配置文件里面的内容是生效,也就是配置文件之间相互导入
4、@Profile
1、多Profile文件
我们在主配置文件编写的时候,文件名可以是 application-{Profile}.properties\yml
默认使用 application.properties的配置
2、激活指定的 application-{Profile}.properties文件
  • 在配置文件中指定spring.profiles.active=dev
    
  • 还可以使用命令行
    在这里插入图片描述

  • 我们还可以使用虚拟机参数

在这里插入图片描述

3、yml支持多文档块
#第一块文档
server:
  port: 8080
spring:
  profiles:
#    激活第三块文档
    active: prod
---
#第二块文档
server:
  port: 8081
spring:
  profiles: dev
---
#第三块文档
server:
  port: 8082
spring:
  profiles: prod
5、配置文件加载位置及其顺序
springboot启动时会扫描一下位置的application.yml或.properties作为springboot的默认配置文件
	1、file:./config/
	2、file:./
	3、classpath:/config
	4、classpath:/

注:

  1. 这是file目录

在这里插入图片描述

  1. 这是classpath目录

在这里插入图片描述

以上是优先级从高到低的顺序,所有位置的文件都会被加载。高优先级会覆盖低优先级的文件的内容

我们可以通过配置spring.config.location来改变默认配置

项目打包好后,我们可以使用命令行参数的形式,启动项目时候去硬盘加载指定的配置文件,指定的配置文件和默认的配置文件会起到互补配置的作用

6、自动配置原理

1、springBoot启动时加载主配置类,主配置类上面标有@SpringBootApplication上面标有 @EnableAutoConfiguration

2、@EnableAutoConfiguration上面有一个@AutoConfigurationPackage注解

  • @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {}
    
    	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    
    		@Override
    		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
                //这个作用是利用注解元信息拿到我们启动类的包名
                //拿到包名后就可以扫描包开始注册里面的组件了
    register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
    		}
        
    
    

3、@EnableAutoConfiguration作用

  • ​ 利用@Import(AutoConfigurationImportSelector.class)给容器中导入一些组件

  • List<String> configurations = SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,      getBeanClassLoader());//扫描所有jar包类路径下的META-INF/spring.factories文件中得到以EnableAutoConfiguration.class为key的值
    
  • 将类路径下的META-INF/spring.factories文件中配置的所有的EnableAutoConfiguration的值加入到了容器中

    • # 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,\
      

      每一个这样的XXXAutoConfiguration类都是容器中的一个组件了,springboot用他们来做自动配置

3、每一个配置类进行自己的自动配置功能

4、以HttpEncodingAutoConfiguration为例解释自动配置原理

//这是一个配置类
@Configuration(proxyBeanMethods = false)
//启动指定类的ConfigurationProperties功能来加载配置文件,将配置文件的值与ServerProperties绑定起来
//@ConfigurationProperties而且将标有这个注解的类加到容器中
@EnableConfigurationProperties(ServerProperties.class)
//spring底层的@Conditional注解,根据不同的条件来让这个配置类生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//判断当前项目有没有这个类
@ConditionalOnClass(CharacterEncodingFilter.class)
//判断配置文件中是否有这个配置server.servlet.encoding=enabled;matchIfMissing = true如果没有那这个配置类也生效
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {}
  • 所有在yml或properties中配置属性都在XXXProperties类中封装这;配置文件中能配置什么就参照这个类

    @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
    public class ServerProperties {
    
    	/**
    	 * Server HTTP port.
    	 */
    	private Integer port;
    
    	/**
    	 * Network address to which the server should bind.
    	 */
    	private InetAddress address;
        
    

5、springboot精髓

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration

  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定

  • 生效的配置类就会给容器中装配很多组件

  • 只要容器中有这些组件,相当于这些功能就有了

  • 定制化配置

    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties

三、日志

1、日志框架
日志门面(日志的抽象层)日志实现
JCL(Commons Logging)、SLF4j、jboss-loggingLog4j、Log4j2、Logback、JUL
左边选一个门面,右边选一个实现
	SLF4j、Log4j、Logback出自同一人,Log4j太老
	所以我们选择SLF4j和Logback
spring底层默认的日志是JCL,springboot默认使用的是SLF4j和Logback
2、SLF4j使用
  • 如何在系统中使用slf4j

    给系统中导入slf4j和logbcak jar包就可以
    日志记录的调用,不应该用实现类,我们应该调用抽象层的方法
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HelloWorld {
      public static void main(String[] args) {
          
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);
         
         
        logger.info("Hello World");
      }
    }
    

    如何使用slf4j图示:
    在这里插入图片描述

  • 如何统一所有框架使用同一个日志实现呢?

    我们需要在日志抽象层之前引入一层抽象层转换

在这里插入图片描述

1、将系统中其他日志框架先排除出去

2、用中间包来替换原有的日志框架
在这里插入图片描述

3、导入slf4j的其他实现

####3、springboot日志关系

在这里插入图片描述

总结

1、springboot底层使用的是slf4j + logback
2、springboot把其他其他日志都替换成了slf4j
3、如果我们引入了其他框架,一定要把这个框架自带的日志从pom中排除掉

springboot能适配所有的日志框架,而且底层使用的是slf4j + logback的方式。我们只需要在引入其他框架时候从pom中排除掉该框架使用的日志即可。

4、日志的使用
1、默认配置

springboot默认给我们配置好了日志

@SpringBootTest
class DemoApplicationTests {

    Logger logger = LoggerFactory.getLogger(getClass());
    //日志级别从低到高trace<debug<info<warn<error
//    调整日志级别打印出的日志会包含此级别及比它高的级别
    @Test
    void contextLoads() {
        logger.trace("这是trace");
        logger.debug("这是debug");
//        springboot默认给我们开启info日志级别
        logger.info("这是info");
        logger.warn("这是warn");
        logger.error("这是error");

    }

}
  • 日志输出的格式

    %d表示时间
    %thread表示线程名
    %-5level 级别从左显示5个字符宽度
    %{logger50} 表示logger名字最长50个字符,否则按照句点分割 
    %msg日志消息
    %n换行
      %-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
    
  • 日志输出成文件

    //1、如果不指定路径那springboot默认在项目下生成springboot.log日志文件
    Logging.file
    //2、在当前磁盘的根目录下创建spring文件夹和log文件夹,使用springboot默认的文件名称(springboot.log)
    Logging.path=/spring/log
    
2、指定配置
Logging SystemCustomization
Logbacklogback-spring.xml, logback-spring.groovy,logback.xml, or logback.groovy
Log4j2log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging)logging.properties

四、Web开发

1、静态资源
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

改变默认的静态资源路径和请求

spring:
  mvc:
#将访问静态资源的请求路径改成请求中加入res。来区别于其他请求
    static-path-pattern: /res/**

  resources:
#修改默认放置静态资源文件夹
    static-locations: [classpath:/haha/]
		@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
			addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
				registration.addResourceLocations(this.resourceProperties.getStaticLocations());
				if (this.servletContext != null) {
					ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
					registration.addResourceLocations(resource);
				}
			});
		}
1、webjars

​ 所有的/webjars/**,都去classpath:/META-INF/resources/webjars/ 找资源

​ webjars就是以jar包的方式引入静态资源;https://www.webjars.org/

在这里插入图片描述

2、放静态资源的文件夹
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
	访问当前项目任何路径(/**)springboot都会去这个四个路径找静态资源
2、请求参数处理
1、rest使用与原理
  • @xxxMapping;

  • Rest风格支持(使用HTTP请求方式动词来表示对资源的操作

  • 以前:**/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户

  • 现在: /user *GET-*获取用户 *DELETE-*删除用户 *PUT-*修改用户 *POST-*保存用户

  • 核心Filter;HiddenHttpMethodFilter

  • 用法: 表单method=post,隐藏域 _method=put

  • SpringBoot中手动开启

  • 扩展:如何把_method 这个名字换成我们自己喜欢的。

Rest原理(表单提交要使用REST的时候)

  • 表单提交会带上**_method=PUT**

  • 请求过来被HiddenHttpMethodFilter拦截

  • 请求是否正常,并且是POST

  • 获取到**_method**的值。

  • 兼容以下请求;PUT.DELETE.PATCH

  • 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。

  • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用****requesWrapper的。

在这里插入图片描述

	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// 这里找到请求对应的handle(也就是对应的controller那个方法来处理)
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					noHandlerFound(processedRequest, response);
					return;
				}
                
                //HandlerMapping:处理器映射。/xxx->>xxxx

在这里插入图片描述

RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。

在这里插入图片描述

所有的请求映射都在HandlerMapping中。

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;

  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping

  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。

  • 如果有就找到这个请求对应的handler

  • 如果没有就是下一个 HandlerMapping

  • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping

3、模板引擎Thymeleaf

常见的模板引擎:JSP 、Freemarker、Thymeleaf

1、引入Thymeleaf依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
2、Thymeleaf语法和使用
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

	private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

	public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";
   //我们只需要将HTML放到classpath:/templates/文件中thymeleaf就可以帮我们自动渲染了
  • 导入thymeleaf名称空间

    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    
  • 使用thymeleaf语法

    <!DOCTYPE html >
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>成功</h1>
    <!--th:text将div里面的文件内容用hello取出来放这里-->
    <div th:text="${hello}"></div>
    </body>
    </html>
    
  • 语法规则

在这里插入图片描述

  • 表达式
Simple expressions: 
	#获取对象的属性、调用方法;使用一些内置对象;内置一些工具对象
    Variable Expressions: ${...} 获取变量值
   	#选择表达式功能和${}一样;多了一点是配合th:object="${session.user}"来使用
    Selection Variable Expressions: *{...} 
    #获取国际化内容
    Message Expressions: #{...} 
    #定义URL 例如:<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>
    Link URL Expressions: @{...} 
    #片段引入表达式
    Fragment Expressions: ~{...}
    
#字面量
Literals 
    Text literals: 'one text' , 'Another one!' ,… 
    Number literals: 0 , 34 , 3.0 , 12.3 ,… 
    Boolean literals: true , false Null 
    literal: null 
    Literal tokens: one , sometext , main ,…
    
#文本操作
Text operations:  
    String concatenation: +  
    Literal substitutions: |The name is ${name}|

#数学运算
Arithmetic operations:
Binary operators: + , - , * , / , %
Minus sign (unary operator): -

#布尔运算
Boolean operations:
Binary operators: and , or
Boolean negation (unary operator): ! , not

#比较运算
Comparisons and equality:
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne )

#条件运算
Conditional operators:
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)

Special tokens:
No-Operation: _
4、SpringMVC自动配置
#springboot已经配置好了springmvc,一下是springboot对springMVC的默认配置

#自动配置了ViewResolver视图解析器;根据方法返回值得到视图对象(View)视图对象决定如何渲染(转发?重定向?)
#我们可以自己写一个视图解析器添加到容器中,springboot自己就会加入进来
• Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
#静态资源文件夹路径WebJars
• Support for serving static resources, including support for WebJars (covered later in this document).
#静态首页访问
• Static index.html support.
#自动注册了转换器(Converter)用于java类型转换,
#格式化器(Formatter)用于日期格式化 自己可以添加格式化转换器放到容器中就可以
• Automatic registration of Converter, GenericConverter, and Formatter beans.
#HttpMessageConverters是springMVC转换HTTP请求和响应的 例如将user转换成json
• Support for HttpMessageConverters (covered later in this document).
#定义错误代码生成规则
• Automatic registration of MessageCodesResolver (covered later in this document).
#初始化WebDataBinder(其实就是将请求数据转换为java对象)
• Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

五、错误处理机制

1、springboot默认错误处理机制
  • 如果是浏览器默认效果返回一个错误页面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ez3NVQqr-1625900819956)(F:\java框架学习笔记\springboot\图片\image-20210704185607526.png)]

  • 如果是客户端访问错误默认给一个json数据

原理:

​ 可以参照ErrorMvcAutoConfiguration这个类错误处理的自动配置类

ErrorMvcAutoConfiguration这个类在容器中添加了这些组件

​ 1、DefaultErrorAttributes

​ 2、BasicErrorController

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

	private final ErrorProperties errorProperties;
    
    //产生HTML数据;浏览器错误请求来到这里
    	@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
	public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse 				response) {
		HttpStatus status = getStatus(request);
		Map<String, Object> model = Collections
				.unmodifiableMap(getErrorAttributes(request, 							         getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
		response.setStatus(status.value());
		ModelAndView modelAndView = resolveErrorView(request, response, status, model);
		return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
	}
//产生JSON数据;其他客户端错误请求来到这里1
	@RequestMapping
	public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
		HttpStatus status = getStatus(request);
		if (status == HttpStatus.NO_CONTENT) {
			return new ResponseEntity<>(status);
		}
		Map<String, Object> body = getErrorAttributes(request, 		               				 getErrorAttributeOptions(request, MediaType.ALL));
		return new ResponseEntity<>(body, status);
	}

​ 3、ErrorPageCustomizer

	@Value("${error.path:/error}")
	private String path = "/error";

​ 4、DefaultErrorViewResolver

	@Override
	public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
		ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
		if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
			modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
		}
		return modelAndView;
	}

	private ModelAndView resolve(String viewName, Map<String, Object> model) {
		String errorViewName = "error/" + viewName;
		TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
				this.applicationContext);
		if (provider != null) {
			return new ModelAndView(errorViewName, model);
		}
		return resolveResource(errorViewName, model);
	}

步骤:系统一旦出现4XX或5XX之类的错误,ErrorPageCustomizer就会生效,就会来到/error请求;就会被BasicErrorController处理

2、如何定制错误

​ 1、定制错误页面

​ 2、定制错误json

六、配置嵌入式Servlet容器

springboot默认使用的是嵌入式servlet容器(Tomcat)

在这里插入图片描述

问题:

  • 那我们如何修改servlet容器相关配置呢?

    1、修改server有关的配置

    server:
      port: 8080
    

    2、我们编写一个WebServerFactoryCustomizer也可以对servlet容器属性值修改

    @Component
    public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    
        @Override
        public void customize(ConfigurableServletWebServerFactory factory) {
            factory.setPort(9000);
    
        }
    }
    
  • springboot能不能支持其他的servlet容器呢?

七、springboot与数据访问

1、JDBC

引入依赖

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

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值