• SpringBoot 是整合 Spring 技术栈的一站式框架,是简化 Spring 技术栈的快速开发脚手架
  • 约定大于配置

文章目录

  • 一 概述
    • 1 第一个 SpringBoot 项目
    • 2 SpringBoot 特性:依赖管理
    • 3 SpringBoot 特性:自动配置
  • 二 SpringBoot 的 IOC容器
    • 1 组件添加:@Configuration
    • 2 组件添加:@Import
    • 3 组件添加:@Conditional
    • 4 引入原生配置文件:@ImportResource
    • 5 配置绑定:@ConfigurationProperties
    • 6 Lombok 的使用
  • 三 yaml 配置文件
    • 1 基本语法
    • 2 使用示例
    • 3 添加配置提示(自动补全)
  • 四 实例:后端管理系统
    • 1 静态资源的配置与访问
    • 2 配置控制器
    • 3 Thymeleaf 抽取页面的相同元素
    • 4 配置拦截器
    • 5 文件上传
    • 6 错误处理
  • 五 注入原生 Web 组件(Servlet,Filter,Listener)
    • 1 使用 Servlet API(推荐)
    • 2 使用 RegistrationBean
  • 六 数据访问
    • 1 导入 JDBC 场景
    • 2 切换 Druid 数据源
    • 3 整合 MyBatis
  • 七 单元测试
    • 1 JUnit5
    • 2 常用注解
    • 3 断言 assert
    • 4 假设 assumption
    • 5 嵌套测试
  • 八 指标监控
    • 1 开启方法
    • 2 常用端点

一 概述

1 第一个 SpringBoot 项目

  1. 导入 maven 依赖
    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.3</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
  1. 创建主程序类,作为启动的入口,注意:启动类的目录一定要在 controller 等目录的至少上一级,或者在 @SpringBootApplication 注解中添加 scanBasePackages 属性
@SpringBootApplication(scanBasePackages = "controller")
public class HelloApplication {public static void main(String[] args) {SpringApplication.run(HelloApplication.class, args);}
}
  1. 创建控制器类以及控制器方法,@RestController = @ResponseBody + @Controller,用于标注控制器类,该控制器的 所有方法 向浏览器返回 控制器方法的返回值
@RestController  // @RestController = @ResponseBody + @Controller,向浏览器返回 该方法的返回值
public class HelloController {@RequestMapping("/hello")public String hello() {return "hello springboot";}
}
  1. 运行主程序类的 main 方法即可,无需更多配置

  2. 如果要修改某些配置,在 resources/application.properties 中修改即可,如:server.port=8888

  3. 如果要导出为 jar 包,需要在 maven 配置文件中添加:

    <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

并执行 maven 的 clean + package 操作

2 SpringBoot 特性:依赖管理

  • 自定义的 SpringBoot 项目的父项目 spring-boot-starter-parent,实现了依赖管理功能
  • 父项目的父项目 spring-boot-dependencies<properties> 标签声明了几乎所有开发中常用的依赖的版本号,实现自动版本仲裁机制(即:引入依赖默认可以不写版本,但是引入非版本仲裁的 jar,要写版本号)
  • 如果想使用依赖的指定版本,需要在当前项目的 maven 配置文件中的 <properties> 标签声明
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置<properties><mysql.version>5.1.43</mysql.version></properties>
  • 场景启动器:spring-boot-starter-*,只要引入 starter,这个场景的所有常规需要的依赖都进行自动引入;所有的启动器底层都依赖 SpringBoot 核心依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.6.3</version><scope>compile</scope>
</dependency>

3 SpringBoot 特性:自动配置

  • 主程序所在包及其下面的所有子包里面的组件(需要 @Component、@Controller… 注解才能称为组件,不加注解无法扫描)都会被默认扫描进来,不用显式地配置组件扫描
  • 各种配置拥有默认值,并按需加载所有自动配置项
  • 主程序类的注解 @SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan(主程序类所在包)
  • 自动配置流程:
    (Ⅰ) SpringBoot 加载所有的自动配置类xxxxxAutoConfiguration类,而非组件)
    (Ⅱ) 每个自动配置类按照条件生效,默认绑定配置文件指定的值(xxxxProperties类)
    (Ⅲ) 生效的配置类就会给容器中装配很多组件
    (Ⅳ) 如果要自定义配置,可以选择:创建 @Bean 替换底层组件,或修改组件获取的配置文件(这些文件最终都映射到 application.properties

二 SpringBoot 的 IOC容器

1 组件添加:@Configuration

  • @Configuration 注解的类,相当于原来的 xml 配置文件
  • 配置类本身也是组件
  • 向 IOC 容器中注入 Bean,对 @Configuration 类中的方法使用 @Bean 注解,将方法的返回对象注入容器
  • 默认情况下,注入容器的对象名为被注解的方法名,如果要修改则向 @Bean 中传递参数
@Configuration
class MyConfig {@Bean  // 根据方法的返回值,向IOC容器中注入对象,默认情况下的对象名为 jerrymousepublic Pet jerrymouse() {return new Pet("Jerry", 3);}
}
  • 代理 Bean 方法:@Configuration(proxyBeanMethod = true) 时(Full 模式),对于 @Bean 注解的方法,如果直接被调用,方法返回的对象是单例的;如果是 @Configuration(proxyBeanMethod = false) (Lite 模式)则非单例
  • Full / Lite 模式与组件依赖问题:
    配置的组件之间无依赖关系,用 Lite 模式,加速容器启动过程,减少判断
    配置类组件之间有依赖关系,用 Full 模式,组件单实例,保证依赖成立

2 组件添加:@Import

  • 对类进行的注解
  • 在 IOC 容器中创建组件,名字为类的全类名
@Import({User.class, Pet.class})
@Configuration(proxyBeanMethods = true)
public class MyConfig {}

3 组件添加:@Conditional

  • 条件装配:满足指定的条件后进行组件装配,可以注解类和方法
  • 具有一系列的子注解,对应不同的情况
    @ConditionalOnBean(name="..."):IOC容器具有指定 Bean 时执行当前组件的装配
    @ConditionalOnMissingBean(name="..."):IOC容器失去指定 Bean 时执行当前组件的装配

4 引入原生配置文件:@ImportResource

  • 用于注解配置类,导入 Spring 的 xml 配置文件
  • 传递参数为配置文件的路径: @ImportResource("classpath:myspringconfig.xml")

5 配置绑定:@ConfigurationProperties

  • 目的是,使得 Java 读取到 properties 文件中的内容,并且把它封装到 JavaBean 中,以供随时修改并使用,即:JavaBean 和配置文件的绑定
  • @ConfigurationProperties 注解需要填入 prefix 属性,以在配置文件中指定其对象的属性值
@Component
@ConfigurationProperties(prefix = "jjjerry")
public class Pet {private String name;private int age;...
}// 在 application.properties 配置中:
// jjjerry.name="杰瑞"
// jjjerry.age=10
  • 如果是自定义类,在自定义类上注解 @ConfigurationProperties 即可;如果非自定义类,需要在配置类上额外注解 @EnableConfigurationProperties(Pet.class),它的作用是开启 Pet 的配置绑定功能,并将 Pet 组件自动注册到容器中

6 Lombok 的使用

  • 简化 Bean 的开发:
@Data  // 创建 getter、setter
@AllArgsConstructor  // 有参构造器
@NoArgsConstructor  // 无参构造器
@ToString  // ...
@EqualsAndHashCode  // ...
public class Person {private String name;private String address;
}
  • @Slf4j 简化日志记录,为注解的类注入了 log 实例:
@Slf4j
@SpringBootApplication
public class Application {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);log.info(String.valueOf(context.getBean("wubai").toString()));}
}@Configuration
class MyConfiguration {@Beanpublic Person wubai() {return new Person("wubai", "taipei");}
}

三 yaml 配置文件

  • 是一种面向数据的配置文件,推荐在配置组件属性时使用

1 基本语法

  1. 大小写敏感
  2. 使用缩进表示层级关系
  3. 缩进不允许使用tab,只允许空格
  4. 缩进的空格数不重要,只要相同层级的元素左对齐即可
  5. '#'表示注释
  6. 使用 key: value 的形式,注意其中的空格
  7. 字符串无需使用引号标注,使用引号时,单引号的转义字符不起作用,双引号起作用
  8. 详细的语法规则

2 使用示例

创建名为 wubai_wujunlin 的组件,并注入 IOC 容器:

@Component(value = "wubai_wujunlin")  // 组件在 IOC 容器中的名字
@ConfigurationProperties(prefix = "wujunlin")  // 组件在配置文件中的前缀
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class Person {private String name;private String address;private List<String> bandMates;
}

依赖的 application.yaml

wujunlin:name: 吴俊霖address: 台北bandMates: [小朱, 大猫, Dino]

3 添加配置提示(自动补全)

在 maven 配置文件添加:

<!--添加自动补全功能--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency><!--打包时不包括自动补全--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></exclude></excludes></configuration></plugin></plugins></build>

四 实例:后端管理系统

1 静态资源的配置与访问

  • 默认静态资源在 resources 目录下的 static 、public… 文件夹内
  • 访问时使用的路径:当前项目根路径/ + 静态资源名
  • 自定义访问静态资源使用的路径:
spring:mvc:static-path-pattern: "/custom_static_url/**"
# 访问时: http://localhost:8080/custom_static_url/bf1.png
  • 欢迎页默认为静态资源路径下的 index.html
  • 输入地址 http://localhost:8080 即可访问欢迎页
  • 在静态资源目录下的 favicon.ico 同样会被自动解析

2 配置控制器

  • 为了避免刷新页面导致表单的重复提交,首次成功登陆后,在控制器方法中返回 "redirect:/main.html" 重定向到新的页面
@Controller
public class IndexController {@GetMapping(value = {"/login", "/"})public String loginPage() {return "login";}@PostMapping("/login")public String processLogin(User user, HttpSession session, Model model) {if (!user.getUsername().isEmpty() && !user.getPassword().isEmpty()) {  // 省略判断逻辑session.setAttribute("loginUser", user);return "redirect:/main.html";  // 使用重定向,防止表单的重复提交} else {model.addAttribute("msg", "账号密码错误");return "login";}}@GetMapping("/main.html")  // 直接访问 http://localhost:8080/main.html 仍然需要经过视图解析器才能获取main.html,而不能直接读取静态资源public String mainPage(HttpSession session, Model model) {if (session.getAttribute("loginUser") != null) {return "main";} else {model.addAttribute("msg", "未登录");return "login";}}
}

3 Thymeleaf 抽取页面的相同元素

官方文档对于 th:insert, th:replace, th:include 的示例

<body><div th:insert="footer :: copy"></div><div th:replace="footer :: copy"></div><div th:include="footer :: copy"></div></body>…will result in:
<body><div><footer>&copy; 2011 The Good Thymes Virtual Grocery</footer></div><footer>&copy; 2011 The Good Thymes Virtual Grocery</footer><div>&copy; 2011 The Good Thymes Virtual Grocery</div></body>

实现步骤

  1. 引入命名空间 <html lang="en" xmlns:th="http://www.thymeleaf.org">
  2. 创建公共部分的 html 页面,使用 th:fragmentid 为公共部分命名
1 使用 fragment 属性命名
<head th:fragment="commonheader"><meta charset="UTF-8"><title>表格页面的公共部分</title>...
</head>2 使用 id 属性命名
<div id="leftmenu" class="left-side sticky-left-side">...
</div>
  1. 导入公共部分:
1 对于 th:fragment 命名的标签,添加属性 th:xx(replace/insert/include)="公共文件名 :: fragment属性"
<div th:replace="common :: commonheader"></div>2 对于 id 命名的标签,添加属性 th:xx(replace/insert/include)="公共文件名 :: #id属性"
<div th:replace="common :: #leftmenu"></div>

4 配置拦截器

  • 拦截路径为 /** 时,静态资源的访问也会被拦截,需要为静态资源路径添加放行
  • 配置类:
@Configuration
public class MyConfig implements WebMvcConfigurer {// 配置拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")  // 静态请求也会被拦截.excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/images/**", "/js/**");  // 放行不登陆就能访问的页面,和静态资源}
}
  • 拦截器的实现:
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object user = request.getAttribute("loginUser");if (user != null) {return true;} else {// 未登录,跳转到登录页// response.sendRedirect("/");  或:request.getRequestDispatcher("/").forward(request, response);log.warn("未登录!!");return false;}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//...HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//...HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

5 文件上传

  1. html 的 from 标签
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data"><div class="form-group"><label for="exampleInputFile">上传单个文件</label><input type="file" name="singleImage" id="exampleInputFile1"></div><div class="form-group"><label for="exampleInputFile">上传多个文件,添加 multiple 属性</label><input type="file" name="multiImage" id="exampleInputFile2" multiple></div></form>
  1. 控制器方法
    使用 MultipartFile 参数类型获取上传文件,其方法 transferTo(...) 用于保存文件到服务器
    @PostMapping("/upload")public String upload(@RequestPart("headerImage") MultipartFile headerImg,@RequestPart("lifeImage") MultipartFile[] lifeImg) throws IOException {// 保存上传文件if (!headerImg.isEmpty()) {String fileName = headerImg.getOriginalFilename();headerImg.transferTo(new File("E:\\" + fileName));}// 多个文件用 for 循环上传// ...return "redirect:/main.html";}

6 错误处理

  • SpringBoot 默认的错误处理机制:error/下的4xx,5xx页面会被自动解析,发生错误时,有精确的错误状态码页面就匹配精确,没有就找 4xx / 5xx;如果都没有就触发白页

五 注入原生 Web 组件(Servlet,Filter,Listener)

1 使用 Servlet API(推荐)

  • 使用 @WebServlet,@WebFilter,@WebListener 注解对应的类,并在启动类注解 @ServletComponentScan 传入 Web 组件位置
@WebServlet(urlPatterns = "/")
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//...}
}
@WebFilter(urlPatterns = {"/**"})
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("过滤器初始化");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("执行过滤操作");filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("过滤器销毁");}
}
@WebListener
public class MyListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("监听到项目初始化");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("监听到项目销毁");}
}

2 使用 RegistrationBean

  • 无需注解
@Configuration
public class MyRegistConfig {@Beanpublic ServletRegistrationBean myServlet(){MyServlet myServlet = new MyServlet();return new ServletRegistrationBean(myServlet,"/my","/my02");}@Beanpublic FilterRegistrationBean myFilter(){MyFilter myFilter = new MyFilter();FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));return filterRegistrationBean;}@Beanpublic ServletListenerRegistrationBean myListener(){MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();return new ServletListenerRegistrationBean(mySwervletContextListener);}
}

六 数据访问

1 导入 JDBC 场景

  • 创建项目时,在 Spring Initializer 中勾选 JDBC 即可
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
  • 默认的数据源是 HikariDataSource
  • 常规配置
spring:datasource:driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123url: jdbc:mysql://localhost:3306/test

2 切换 Druid 数据源

  • 引入依赖
        <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency>
  • 配置示例
spring:datasource:driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: 123url: jdbc:mysql://localhost:3306/testdruid:aop-patterns: com.atguigu.admin.*  #监控SpringBeanfilters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)stat-view-servlet:   # 配置监控页功能enabled: truelogin-username: adminlogin-password: adminresetEnable: falseweb-stat-filter:  # 监控webenabled: trueurlPattern: /*exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'filter:  # 配置开启的filterstat:    # 对上面filters里面的stat的详细配置slow-sql-millis: 1000logSlowSql: trueenabled: truewall:enabled: trueconfig:drop-table-allow: false

3 整合 MyBatis


七 单元测试

1 JUnit5

  • JUnit 5 = JUnit Platform(基础框架) + JUnit Jupiter(核心) + JUnit Vintage(向下兼容)
  • JUnit Platform: 在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入
  • JUnit Jupiter: JUnit Jupiter 提供了 JUnit5 的新的编程模型,是 JUnit5 新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行
  • JUnit Vintage: JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎

2 常用注解

  • @Test :标注方法是测试方法
  • @ParameterizedTest:表示方法是参数化测试
  • @RepeatedTest:重复执行测试方法
  • @DisplayName:为测试类或者测试方法设置展示名称
  • @BeforeEach :在每个单元测试之前执行
  • @AfterEach :在每个单元测试之后执行
  • @BeforeAll :在所有单元测试之前执行,方法需要 static 修饰
  • @AfterAll :在所有单元测试之后执行,方法需要 static 修饰
  • @Tag :表示单元测试类别
  • @Disabled :不执行测试类或测试方法
  • @Timeout :测试方法运行如果超过了指定时间,将会返回错误
  • @ExtendWith :为测试类或测试方法提供扩展类引用

3 断言 assert

  1. 简单断言
方法 说明
assertEquals 判断两个对象或两个原始类型是否相等
assertEquals 判断两个对象或两个原始类型是否相等
assertNotEquals 判断两个对象或两个原始类型是否不相等
assertSame 判断两个对象引用是否指向同一个对象
assertNotSame 判断两个对象引用是否指向不同的对象
assertTrue 判断给定的布尔值是否为 true
assertFalse 判断给定的布尔值是否为 false
assertNull 判断给定的对象引用是否为 null
assertNotNull 判断给定的对象引用是否不为 null
  1. 数组断言
  • 通过 assertArrayEquals(...) 方法来判断两个对象或原始类型的数组是否相等
  • 对于对象类型数组,比较的方式是逻辑等于,即调用 equals 方法
@Test
@DisplayName("array assertion")
public void array() {assertArrayEquals(new int[]{1, 2}, new int[] {1, 2});
}
  1. 组合断言
  • 要求一系列断言同时满足
  • 使用 lambda 表达式提供方法实参(lambda 表达式对应函数式编程)
@Test
@DisplayName("assert all")
public void all() {assertAll("Math",() -> assertEquals(2, 1 + 1),() -> assertTrue(1 > 0));
}
  1. 异常断言
  • assertThrows 方法需要的参数:异常类型的 class 属性,需要抛出异常的语句的 lambda 表达式
@Test
@DisplayName("异常测试")
public void exceptionTest() {Assertions.assertThrows(ArithmeticException.class, () -> System.out.println(1 % 0));
}
  1. 超时断言
@Test
@DisplayName("超时测试")
public void timeoutTest() {Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
}
  1. 快速失败
@Test
@DisplayName("fail")
public void shouldFail() {fail("This should fail");
}

4 假设 assumption

  • 假设作为单元测试的前提条件,如果前提条件不满足则没有进行测试的必要
  • 不满足的断言会使得测试方法失败;不满足的前置条件只会使得测试方法的执行终止,而不会引起测试失败
  • assumeTrueassumFalse 确保给定的条件为 true 或 false,不满足条件会使得测试执行终止
  • assumingThat 的参数是表示条件的布尔值和对应的 Executable 接口的实现对象,只有条件满足时,Executable 对象才会被执行;当条件不满足时,测试执行并不会终止
@DisplayName("前置条件")
public class AssumptionsTest {private final String environment = "DEV";@Testpublic void simpleAssume() {assumeTrue(Objects.equals(this.environment, "DEV"));assumeFalse(() -> Objects.equals(this.environment, "PROD"));}@Testpublic void assumeThenDo() {assumingThat(Objects.equals(this.environment, "DEV"),() -> System.out.println("In DEV"));}
}

5 嵌套测试

  • 目的是将测试过程结构化,把相关的测试方法组织在一起
  • 对测试类及其内部类使用 @Nested 注解,实现嵌套测试
@DisplayName("A stack")
class TestingAStackDemo {Stack<Object> stack;// 最外层测试方法@Testvoid isInstantiatedWithNew() {new Stack<>();}// 嵌套第一层测试类@Nestedclass WhenNew {@BeforeEachvoid createNewStack() {stack = new Stack<>();}@Testvoid isEmpty() {assertTrue(stack.isEmpty());}// 嵌套第二层测试类@Nested@DisplayName("after pushing an element")class AfterPushing {String anElement = "an element";@BeforeEachvoid pushAnElement() {stack.push(anElement);}@Test@DisplayName("it is no longer empty")void isNotEmpty() {assertFalse(stack.isEmpty());}}}
}

八 指标监控

  • 微服务在云上部署以后,都需要对其进行监控、追踪、审计、控制等。SpringBoot 抽取了Actuator 场景,使得每个微服务可获得生产级别的应用监控、审计等功能

1 开启方法

  1. 引入场景依赖
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
  1. 配置暴露端点(endpoint)及暴露方式
management:endpoints:enabled-by-default: true #暴露所有端点信息web:exposure:include: '*'  #以web方式暴露
  1. 访问 http://localhost:8080/actuator/... 监控对应指标

2 常用端点

  • Health:健康状况
  • Metrics:运行时指标
  • Loggers:日志记录

后端学习 - SpringBoot相关推荐

  1. 物流快递系统前、后端+Java语言+SpringBoot项目+MVC三层架构+maven+Mysql+Tomcat+可以用于学习SpringBoot项目入门

    物流快递系统前.后端+Java语言+SpringBoot项目+MVC三层架构+Mysql+Tomcat+可以用于学习SpringBoot项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资 ...

  2. 小白自学Java后端学习计划(附带学习视频)

    项目交流群 QQ群: 994793967 ,欢迎进群交流讨论 一.Java基础 java基础语法 集合 io 多线程 并发 反射 网络编程 注意:对于Java基础,其中集合和io是初学Java后端的时 ...

  3. 【java后端学习路线3】SSM+Linux+Git学习指南,985本海硕自学转码

    JAVA后端学习路线 路线总览 javase->Mysql->计算机网络->JavaWeb->Maven(1)->Spring->SpringMVC->Myb ...

  4. 学习Springboot一之Springboot+Mybatis(注解形式)+Mysql+Web简单Demo

    学习SpringBoot,通过Springboot简单配置连接Mysql数据库,采用Mybatis注解方式实现数据库"增.删.改.查",结合Spring web实现页面呈现后,. ...

  5. 大学四年Java后端学习路线规划,所有私藏资料我都贡献出来了,不看毕业肯定后悔!!!

    一定要走在学校前面自学,规划好自己的时间,按照自己的路线走. 大学四年Java后端学习路线规划,所有私藏资料我都贡献出来了,不看毕业肯定后悔!!! 学习路线与资源方法 一.第一件事,很重要!!! 二. ...

  6. Java后端学习路线分享

    Java后端学习路线?最近有些网友问我如何学习 Java 后端,还有些是想从别的方向想转过来,但都不太了解 Java 后端究竟需要学什么,究竟要从哪里学起,哪些是主流的 Java 后端技术等等,导致想 ...

  7. Java——Web后端学习路线

    文章目录 Java后端学习路线 第一部分: Java基础 第二部分: Java高级 第三部分: JavaWEB 第四部分: 主流框架和项目管理 第五部分: 分布式 微服务 并行架构 第六部分 : De ...

  8. Java后端学习日记(二):POJO的基本概念,编写,转化和简化

    专栏目录 Java后端学习日记(一):第一个Springboot应用--Hello World! Java后端学习日记(二):POJO的基本概念,编写,转化和简化 Java后端学习日记(三):Spri ...

  9. 大厂招聘-校招生/实习生 后端学习路线-Java

    大厂招聘-校招生/实习生 后端学习路线-Java 我是一个Java后端开发人员,校招生,在面试过程中深感Java作为红海,找工作投简历的人那是一个多呀,打个比喻,100人找工作,20个是算法,10个是 ...

最新文章

  1. Java黑皮书课后题第7章:7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值
  2. Java程序优化之享元模式
  3. linux安装库文件下载,Linux下的Curses库的下载与安装
  4. 哈希表(散列表)基础概念与经典题目(Leetcode题解-Python语言)之下——设计键
  5. Flask-SQLAlchemy 对数据库的过滤查询
  6. 扩展 HashMap
  7. 客户机无法上网,ping 127.0.0.1提示unable to contact IP driver ,error code2
  8. 【bzoj3573】 Hnoi2014—米特运输
  9. alisql 与mysql_【阿里云资讯】AliSQL 5.6.32 vs MySQL 5.7.15抢鲜测试-阿里云开发者社区...
  10. 第十一章 面向对象设计
  11. 华为交换机系统软件升级和安全漏洞修复教程
  12. 马尔可夫链(Markov chain)的基本认识
  13. 数据结构——查找与排序
  14. 项目经理进阶:如何做好一个领导者
  15. 人工智能行业每日必读(01·17)
  16. mysql忘记密码win10_win10 mysql8.0.12 忘记root密码如何重置密码
  17. MySQL 高级查询
  18. 编译原理学习笔记 5.1 翻译文法和语法制导翻译
  19. 华为服务器怎么连接显示器,华为MateBook怎么连接外接显示器/投影仪?
  20. Swift语言学习(二)

热门文章

  1. DotNet Core 介绍
  2. C#趣味程序---爱因斯坦的台阶问题
  3. NetBeans安装提示neatbeans cannot find java 1.8 or higher
  4. Android之线程池
  5. Android之webview与js交互
  6. 【iVX 初级工程师培训教程 10篇文拿证】05 画布及飞机大战游戏制作
  7. mysql安装10045_mysql数据库5.6.45安装后的配置(离线安装包版)
  8. java程序员遇到的问题_JAVA程序员最常遇见的10个异常
  9. python后面空格报错_python中空格和table混用报错原因
  10. 原来医生的处方不是随便乱写的...