亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Springboot企業級開發學習:從入門到實踐

標簽:
SpringBoot
概述

Spring Boot企业级开发学习涵盖了从环境搭建到项目部署的全过程,包括自动配置、依赖注入、数据库集成和Web应用开发等内容。本文通过详细示例和代码演示,帮助开发者掌握Spring Boot的核心功能和企业级应用开发技巧。此外,文章还介绍了项目监控、安全控制、性能优化及持续集成等高级主题。

Spring Boot企业级开发学习:从入门到实践
Spring Boot简介与环境搭建

Spring Boot的背景和优势

Spring Boot是由Pivotal团队提供的框架,旨在简化基于Spring框架的开发过程。它通过约定优于配置的方式,极大地减少了开发者在配置Spring应用程序时的工作量,使开发者能够专注于编写业务代码。Spring Boot的核心优势包括:

  1. 自动配置:Spring Boot可以根据应用类型自动配置大多数Spring应用程序。
  2. 独立运行:支持以WAR或者JAR包的形式发布应用,并且可以内嵌Tomcat、Jetty或者Undertow模块。
  3. 热部署:支持热部署,修改代码后无需重启应用即可看到效果。
  4. 全面的开发工具支持:Spring Boot支持Spring Tool Suite、Spring Tools 4、IntelliJ IDEA等开发工具。
  5. 开箱即用:内置了大量的库和框架,包括Thymeleaf、JPA、MyBatis等,使得开发过程更加便捷。

开发环境配置

为了开始使用Spring Boot进行开发,首先需要配置好开发环境。开发环境的配置包括Java开发工具包(JDK)、构建工具(Maven或Gradle)以及集成开发环境(IDE)。以下是配置步骤:

  1. 安装JDK

    • 下载并安装JDK,确保安装成功后环境变量配置正确。
    • 检查安装是否成功,可通过命令行输入java -version查看。
  2. 安装Maven

    • 下载Maven并解压到指定目录。
    • 配置环境变量,确保Maven的bin目录路径添加到系统环境变量PATH中。
    • 通过命令mvn -v验证Maven是否安装成功。
  3. 安装IDE
    • 推荐使用IntelliJ IDEA或Eclipse。安装IDE后,通过File -> New -> Project创建一个新的项目。

创建第一个Spring Boot项目

创建一个新的Spring Boot项目可以通过IntelliJ IDEA进行。以下是详细步骤:

  1. 打开IntelliJ IDEA,点击File -> New -> Project
  2. 在New Project窗口,选择Spring Initializr,然后点击Next
  3. 输入Group ID和Artifact ID,Group ID通常为项目名的包名,Artifact ID为项目的名称。例如:
    Group ID: com.example
    Artifact ID: demo
  4. 输入项目名DemoApplication
  5. 选择JDK版本和项目存放位置,点击Next
  6. 在弹出的窗口中,选择依赖项,例如WebJPAThymeleaf等,点击Next
  7. 点击Finish完成项目创建。

项目创建完成后,IntelliJ IDEA会自动生成基本的项目结构,包括主启动类、配置文件等。接下来可以编写第一个Spring Boot应用了。

主启动类

在项目中,主启动类是运行项目的关键。主启动类通常命名为Application,位于src/main/java目录下。以下是一个简单的主启动类示例:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

上面的代码中,@SpringBootApplication注解是Spring Boot的核心注解,它包含了@Configuration@EnableAutoConfiguration@ComponentScan三个注解。main方法用于启动Spring Boot应用。

实践示例:创建一个简单的RESTful API

接下来,我们将创建一个简单的RESTful API来展示如何使用Spring Boot的@RestController注解和@GetMapping注解。

src/main/java/com/example/demo目录下创建一个新的Java类HelloController

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

在这个类中,@RestController注解用于标记该类为控制器,并且指定了返回数据的数据类型。@GetMapping注解用于处理HTTP GET请求,路径为/hello,该方法返回字符串"Hello, Spring Boot!"。

运行项目时,可以通过浏览器或Postman访问http://localhost:8080/hello来测试这个RESTful API。

Spring Boot核心概念与配置

依赖注入与自动配置

在Spring Boot中,依赖注入(Dependency Injection)和自动配置是两个重要的概念,它们极大地简化了开发过程。

依赖注入

依赖注入是一种设计模式,通过它将组件之间的依赖关系从代码中移除,转而由框架来管理。在Spring Boot中,依赖注入主要通过@Autowired注解来实现。以下是一个简单的例子:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

    @Autowired
    private MyService myService;

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

    @Override
    public void run(String... args) throws Exception {
        myService.doSomething();
    }
}

在上面的代码中,@Autowired注解用于自动注入MyService类的实例。MyService类可能如下所示:

package com.example.demo;

public class MyService {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

自动配置

Spring Boot的自动配置功能会根据类路径中的jar包和应用程序类来自动配置Spring应用程序。例如,如果项目中包含spring-boot-starter-web依赖,Spring Boot会自动配置Tomcat服务器、Spring MVC和其他相关组件。

配置文件详解(application.properties/application.yml)

Spring Boot使用外部配置文件来管理应用程序的配置。配置文件可以是application.properties或者application.yml。以下是配置文件的基本用法:

application.properties

# 端口号
server.port=8080

# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root

# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

application.yml

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

项目监控与健康检查

Actuator监控

Spring Boot Actuator提供了一套工具来帮助管理和监控生产环境中的应用。通过Actuator,可以获取应用的运行时信息,包括健康状态、环境信息、线程信息、HTTP请求指标等。

要启用Actuator,需要在项目中添加spring-boot-starter-actuator依赖:

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

启用后,可以通过http://localhost:8080/actuator访问Actuator提供的所有端点。例如,访问/health端点可以获取应用的健康状态。

自定义健康检查

可以根据需要自定义健康检查。例如,创建一个自定义的健康检查类,并实现HealthIndicator接口:

package com.example.demo;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class CustomHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        boolean isHealthy = // 根据自己的业务逻辑判断是否健康
        return Health.status(isHealthy ? Health.Status.UP : Health.Status.DOWN).build();
    }
}

这样,自定义的健康检查也会被Actuator自动检测到,并在/health端点中显示结果。

数据访问与数据库集成

JPA与Spring Data的使用

JPA(Java Persistence API)是Java EE中用于对象关系映射(ORM)的标准规范。Spring Data JPA是Spring Data的一个子项目,提供了基于JPA的数据访问抽象层。

实体类

实体类用于表示数据库中的表结构。例如,创建一个表示用户信息的实体类User

package com.example.demo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // 构造函数、getter 和 setter 方法省略
}

仓库接口

在Spring Data JPA中,可以通过定义一个继承自JpaRepository的接口来提供基本的数据访问方法,例如:

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);
}

在这个接口中,JpaRepository<User, Long>表示User类型的实体对象,主键类型为Long。Spring Data会根据接口中的方法自动推断出相应的SQL查询。

服务层

在服务层中,可以使用仓库接口提供的方法来操作数据库:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        return userRepository.save(user);
    }

    public User findByName(String name) {
        return userRepository.findByName(name);
    }
}

数据库连接与事务管理

Spring Boot默认使用H2内嵌数据库,但也可以配置连接其他数据库,如MySQL、PostgreSQL等。以下是如何配置MySQL数据库连接的示例:

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

事务管理

Spring Boot内置了Spring的事务管理功能。可以通过@Transactional注解来管理事务。例如:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void saveUser(User user) {
        userRepository.save(user);
        // 其他操作
    }
}

测试数据库操作

为了确保数据库操作的正确性,可以编写单元测试来验证服务层的行为。例如,使用Spring Boot的@DataJpaTest注解来测试UserRepository

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import static org.junit.jupiter.api.Assertions.*;

@DataJpaTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void testSaveUser() {
        User user = new User();
        user.setName("John");
        user.setEmail("[email protected]");

        userRepository.save(user);

        User foundUser = userRepository.findByName("John");
        assertNotNull(foundUser);
        assertEquals("John", foundUser.getName());
    }
}
常见Web应用开发

RESTful API设计与实现

RESTful API是一种设计良好的Web服务标准,它遵循REST(Representational State Transfer)架构风格。以下是如何使用Spring Boot实现一个简单的RESTful API。

REST Controller

创建一个REST控制器来处理HTTP请求:

package com.example.demo;

import org.springframework.web.bind.annotation.*;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users")
    public Iterable<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping("/users/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        return userService.save(user);
    }

    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
    }
}

测试REST API

可以使用RestTemplateMockMvc来测试REST API。以下是一个使用MockMvc的示例:

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testGetAllUsers() throws Exception {
        mockMvc.perform(get("/users"))
               .andExpect(status().isOk());
    }

    @Test
    public void testGetUserById() throws Exception {
        mockMvc.perform(get("/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("John"));
    }

    @Test
    public void testCreateUser() throws Exception {
        User user = new User();
        user.setName("John");
        user.setEmail("[email protected]");

        mockMvc.perform(post("/users")
                        .contentType("application/json")
                        .content(new ObjectMapper().writeValueAsString(user)))
               .andExpect(status().isOk());
    }

    // 其他测试方法省略
}

使用Spring Security进行安全控制

Spring Security是一个强大的安全框架,可以用于保护Spring应用程序的安全。以下是如何在Spring Boot中启用Spring Security的示例。

添加依赖

pom.xmlbuild.gradle文件中添加Spring Security依赖:

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

配置安全

创建一个配置类来启用Spring Security,并定义安全规则:

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        auth.inMemoryAuthentication()
                .withUser(user);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
            .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
                .logout()
                .permitAll();
    }
}

测试安全控制

可以使用MockMvc来测试安全控制是否生效:

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@SpringBootTest
@AutoConfigureMockMvc
public class SecurityTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testAccessDenied() throws Exception {
        mockMvc.perform(get("/admin"))
               .andExpect(status().is3xxRedirection());
    }
}

前端模板与静态资源处理

Spring Boot支持多种前端模板引擎,例如Thymeleaf、FreeMarker等。以下是如何使用Thymeleaf渲染HTML页面的示例。

添加依赖

pom.xmlbuild.gradle文件中添加Thymeleaf依赖:

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

创建模板

src/main/resources/templates目录下创建一个HTML模板文件,例如index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
</head>
<body>
    <h1>Welcome to Spring Boot</h1>
    <p>Name: <span th:text="${name}"></span></p>
</body>
</html>

创建控制器

创建一个控制器来渲染模板页面:

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("name", "John");
        return "index";
    }
}

静态资源处理

Spring Boot默认从src/main/resources/static目录下提供静态资源。例如,可以在src/main/resources/static目录下创建一个css文件夹,并添加一个style.css文件:

body {
    background-color: #f0f0f0;
}

静态资源文件会被自动加载并提供给客户端。

深入企业级功能开发

日志管理与集成

日志是记录应用程序运行时信息的重要手段,Spring Boot通过SLF4J和Logback框架提供了强大的日志管理功能。以下是如何配置和使用日志的示例。

配置日志

application.properties中配置日志级别和输出格式:

# 配置日志级别
logging.level.root=INFO

# 配置日志文件名和路径
logging.file.name=logs/app.log
logging.file.path=logs

# 配置日志输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} - %msg%n

使用日志记录器

在代码中注入日志记录器,并使用它来记录日志信息:

package com.example.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public void doSomething() {
        log.info("Doing something...");
    }
}

异步处理与任务调度

异步处理

Spring Boot支持异步方法调用,可以用于提升应用的响应性能。以下是如何启用异步支持的示例:

  1. 在主类上添加@EnableAsync注解:
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  1. 在需要异步执行的方法上添加@Async注解:
package com.example.demo;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Async
    public void doAsyncTask() {
        // 异步执行的任务代码
    }
}

任务调度

Spring Boot支持使用@Scheduled注解来定时执行任务。例如,创建一个定时任务每分钟执行一次:

package com.example.demo;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

    @Scheduled(fixedRate = 60000)
    public void reportCurrentTime() {
        System.out.println("The time is now: " + System.currentTimeMillis());
    }
}

性能优化与缓存机制

使用缓存

Spring Boot支持使用不同的缓存库,例如CaffeineEhcache。以下是如何启用缓存的示例:

  1. 在主类上添加@EnableCaching注解:
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  1. 在需要缓存的方法上添加@Cacheable注解:
package com.example.demo;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

@Service
public class UserService {

    @Cacheable(value = "users")
    public List<User> getAllUsers() {
        // 模拟数据库查询
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setName("User " + i);
            users.add(user);
        }
        return users;
    }
}

性能优化

性能优化可以通过多种方式实现,例如优化数据库查询、减少HTTP请求、使用异步处理等。以下是一个简单的数据库查询优化示例:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Cacheable(value = "users")
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

在上面的代码中,getAllUsers方法使用了@Cacheable注解来缓存查询结果,从而减少了数据库的访问次数。

项目部署与运维

Java应用打包与发布

Spring Boot应用可以通过Maven或Gradle打包成可执行的JAR或WAR文件。

打包JAR文件

pom.xmlbuild.gradle文件中配置打包插件:

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

然后运行以下命令来打包应用:

mvn clean package

或者

./gradlew bootJar

生成的JAR文件可以在target目录下找到。

运行JAR文件

打包完成后,可以通过以下命令运行JAR文件:

java -jar target/demo-0.0.1-SNAPSHOT.jar

部署到Tomcat与Docker容器

部署到Tomcat

要将Spring Boot应用部署到Tomcat,通常需要将应用打包成WAR文件。修改pom.xml文件中的packaging属性:

<packaging>war</packaging>

然后运行打包命令:

mvn clean package

生成的WAR文件可以在target目录下找到。将WAR文件复制到Tomcat的webapps目录下即可部署。

部署到Docker容器

Docker可以用来打包应用及其运行环境,使之能够方便地在任何环境中运行。以下是如何使用Docker来部署Spring Boot应用的示例:

  1. 创建Dockerfile文件:
FROM openjdk:11-jre-slim
COPY target/demo-0.0.1-SNAPSHOT.jar /app/app.jar
ENTRYPOINT ["java","-jar","/app/app.jar"]
  1. 构建Docker镜像:
docker build -t demo-app .
  1. 运行Docker容器:
docker run -p 8080:8080 demo-app

持续集成与持续部署

持续集成(CI)和持续部署(CD)是现代软件开发的重要实践。以下是如何使用Jenkins来实现CI/CD的示例:

配置Jenkins

  1. 安装Jenkins并配置Jenkinsfile:
pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }

        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }

        stage('Deploy') {
            steps {
                sh 'docker build -t demo-app .'
                sh 'docker run -p 8080:8080 demo-app'
            }
        }
    }
}
  1. 创建Jenkins任务并配置Jenkinsfile:

在Jenkins中创建一个新的任务,选择“Pipeline”类型,然后从SCM中配置Jenkinsfile的路径。

测试Jenkins配置

提交代码到版本控制系统(如Git),触发Jenkins构建任务。如果一切配置正确,Jenkins将自动构建、测试并部署应用。

总结与参考资料

本文详细介绍了Spring Boot企业级开发的各项内容,包括环境配置、核心概念、数据库集成、Web应用开发、企业级功能开发以及项目部署和运维。通过实际示例和代码演示,帮助读者更好地理解和掌握Spring Boot的使用方法。

参考其他资源:

  1. 官方文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
  2. 官方GitHub仓库:https://github.com/spring-projects/spring-boot
  3. 春风博客(Spring Boot专题):https://spring.io/blog
  4. 慕课网Spring Boot课程:http://www.xianlaiwan.cn/course/list/springboot
點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消