Java主流框架技术及少量前端框架使用与总结

Vue CLI

关于Vue CLI

Vue CLI是Vue官方推出的一个脚手架客户端工具,使用它可以快速的构建一个基于Vue的单页面应用。

安装Node.js

下载 https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/v16.14.2/node-v16.14.2-x64.msi 并安装,安装过程中没有特殊选项。

安装完成后,可以在命令提示符窗口或终端中执行npm -v检查是否安装成功:

npm -v

安装Node.js的主要目的就是为了使用npm

npm = Node Package Manager

在使用npm之前,需要先将npm源配置为国内的某个npm源服务器

npm config set registry https://registry.npm.taobao.org

设置后,还可以通过get命令查看npm源:

npm config get registry

注意:以上命令并不能检查你的配置值是否正确!

安装Vue CLI

需要安装Vue CLI以后,才可以通过它的命令来创建Vue CLI项目、启动项目等。

当安装了npm并配置npm源之后,安装Vue CLI的命令是:

npm install -g @vue/cli

安装过程中没有出现Error字样即为成功

安装过程中出现Error字样即为失败,可以:

  • 先通过npm config get registry检查npm源是否是:https://registry.npm.taobao.org/
  • 重新执行以上安装Vue CLI命令
  • 不要在Power Shell下执行命令(命令提示符前面为PS字样)
  • 如果使用Mac OS(苹果操作系统),建议在命令前添加sudo以使用管理员权限来执行命令

如果安装过程中卡住长时间没有反应,可以按下Ctrl + C强制终止,然后再次执行命令进行尝试。

当安装完成之后,可以使用vue -V来查看Vue CLI版本,也可以用于检验刚才的安装是否成功:

vue -V

创建Vue CLI项目

通常,应该创建某个文件夹,用于存放项目,例如在D盘下创建Vue-Workspace文件夹,然后,在命令提示符窗口中进入此文件夹:

D:

cd D:\Vue-Workspace

接下,通过vue create 项目名称命令来创建Vue CLI项目:

vue create jsd2204-csmall-web-client-teacher

注意:敲完以后命令之后只能按1下回车键,即使卡住了,也不要反复按回车!

注意:如果接下来的操作过程中选错,按下Ctrl + C强制终止,再重新创建项目。

按1下回车后,稍微等待一会,会出现创建项目时的选项,需要选择:

Manually select features

Babel

Vuex

Router

2.x

直接回车

In package.json

直接回车

最后,看到Successfully created project jsd2204-csmall-web-client-teacher字样,即表示创建成功。

启动项目

通过IntelliJ IDEA打开项目,在IntelliJ IDEA的Terminal窗口中执行:

npm run serve

执行以上命令即可启动项目,启动成功后,即可看提示:

App running at:

  - Local:   http://localhost:8080/

提示:可能某些电脑上会显示多个网址,这并不重要。

打开浏览器,通过 http://localhost:8080/ 网址进行访问,即可看到默认的页面。

关于占用端口:通过npm run serve启动的Vue CLI会默认尝试占用8080端口,如果尝试占用的端口号已经被其它进程占用,则会自动顺延一位,即尝试占用8081端口,如果仍被占用,会继续顺延……

也可以显式的指定某个端口号,在package.json中修改scriptsserve属性,例如配置为:

"serve": "vue-cli-service serve --port 8888"

则当前项目启动时会占用8888端口。

停止服务

当项目启动后,在提示了启动成功的端口窗口中,按下Ctrl + C即可停止服务。

提示:有时按下Ctrl + C后没有响应,可能反复多按几次,或按了Ctrl + C后回车。

提示:其实,只要按下了Ctrl + C,当前服务就已经停止了,后续可能出现终止批处理操作吗(Y/N)?提示,无论选择Y还是N,都无所谓。

重启服务

没有此功能

Vue CLI项目结构

  • package.json:相当于Maven项目中的pom.xml文件,主要配置了当前项目的依赖项,如果不太熟悉此文件,不建议手动修改
  • package-lock.json:此文件是自动生成的,不建议手动修改
  • [node_modules]:当前项目中各依赖项对应的源文件,通常,此文件夹的内容较多,且共享项目时,通常不会包含此文件夹,例如GIT仓库中的项目文件通常不包含此文件夹的内容,执行npm install命令将根据package.json下载相关的依赖项到此文件夹中
  • [src/views]:是建议的存放.vue视图文件的文件夹
  • [src/router/index.js]:是项目的路由配置文件,它配置了各路径与.vue视图组件的对应关系
  • public/index.html:项目中唯一的HTML文件,其内部在页面设计中添加了<div id="app"></div>标签
  • src/App.vue:项目中默认的视图文件,是被index.html显示的

关于.vue视图文件

是Vue CLI中用于设计页面的源文件,可以此文件中设计页面的元素、CSS样式、JavaScript。

此文件可以有3个根节点(元素):

  • <template>:在其内部设计页面元素,且此节点(元素)必须有且仅有1个直接子节点(元素),通常,会在<template>下添加<div>,然后,在<div>内部再设计页面
  • <style>:在其内部配置CSS样式
  • <script>:在其内部编写JavaScript程序

提示:根据页面设计,某些.vue文件可能没有<style>,或可能没有<script>

关于路由配置

src/router/index.js中,使用了routes数组常量配置路由,主要是配置了各路径与视图组件的对应关系,所以,在数组中的各个元素值就是一个个的路由对象,每个路由对象至少要配置pathcomponent这2个属性。

提示:在路由对象中,name属性不是必须的。

关于component属性,有2种配置方式,第1种是默认导入的,通常会在当前文件的顶部使用import语句导入并命名,然后,此component属性的值就是导入时取的名字,第2种是使用箭头函数import导入的,通常,在各项目中,只会有1个是默认导入的。

关于router-view

.vue文件中,可以添加<router-view/>,此标签本身是没有显示效果的,它表示“此处将由另一个视图组件来完成显示,且,到底由哪个视图组件来显示,取决于路由配置与当前访问的URL”。

嵌套路由

在开发实践中,必然存在某些页面是完全没有相同之处的,所以,通常,在App.vue的设计中,只保留一个<router-view/>,所以,具体的显示都由各个.vue文件来决定,默认并没有共同(复用)的部分!但是,也一定存在多个页面之间存在共同的部分,所以,在某个.vue中可能还需要再加一个<router-view/>,像这种本身显示在App.vue中的<router-view/>位置、自身内部也包含<router-view/>的,称之为“嵌套路由”。

src/router/index.js中,如果某个视图有<router-view/>,在配置时,应该通过children属性配置子级路由(被嵌套的那层路由),此children属性的写法与根级的routes完全相同,例如:

const routes = [

    {

        path: '/home',

        component: () => import('../views/HomeView.vue'),

        children: [

            {

                path: '/brand-list',

                component: () => import('../views/BrandListView.vue')

            },

            {

                path: '/brand-add-new',

                component: () =>import('../views/BrandAddNewView.vue')

            }

        ]

    },

    // 省略其它代码
}

一旦使用了嵌套路由,必须有某个View是不完整的(其内部有某个区域使用了<router-view/>,是由其它View来负责显示的),这样的View不应该能够被直接访问,所以,通常会配置上redirect属性,表示“重定向”的意思,一旦访问这个View对应的路径,就会自动跳转到重定向配置的路径上,例如:

const routes = [

    {

        path: '/sys-admin',

        component: () => import('../views/HomeView.vue'),

        redirect: '/sys-admin/index',  // 重定向

        // 其它代码

另外,在使用了嵌套路由时,通常,设计的子级路由中的URL会有共同的前缀,例如:

const routes = [

    {

        path: '/sys-admin',

        component: () => import('../views/HomeView.vue'),

        redirect: '/sys-admin/index',

        children: [

            {

         // 以下路径使用了 /sys-admin 作为前缀

                path: '/sys-admin/temp/brand/list',

                component: () => import('../views/sys-admin/temp/BrandListView.vue')

            },

            {

                // 以下路径使用了 /sys-admin 作为前缀

                path: '/sys-admin/temp/brand/add-new',

                component: () => import('../views/sys-admin/temp/BrandAddNewView.vue')

            },

则,在配置子级路径的path时,可以不使用/作为第1个字符,然后,配置值只需要写/sys-admin右侧的部分,例如:

const routes = [

    {

        path: '/sys-admin',

        component: () => import('../views/HomeView.vue'),

        redirect: '/sys-admin/index',

        children: [

            {

         // 实际路径是父级路由的path与当前path的组合:/sys-admin/temp/brand/list

                path: 'temp/brand/list',

                component: () => import('../views/sys-admin/temp/BrandListView.vue')

            },

            {

                // 实际路径是父级路由的path与当前path的组合:/sys-admin/temp/brand/add-new

                path: 'temp/brand/add-new',

                component: () => import('../views/sys-admin/temp/BrandAddNewView.vue')

            },

在Vue CLI中使用Element UI

在终端中,需要先安装Element UI(本质上是下载Element UI相关的文件到本项目的node_modules中)。

必须保证当前命令提示符是当前项目下(与执行npm run serve等命令的位置相同,必须保证当前位置下有package.json文件)!

安装的命令是:

npm i element-ui -S

注意:以上命令最后的S是大写的!

安装完成后,需要在src/main.js中进行配置:

import ElementUI from 'element-ui';

import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

在使用Element UI中的<el-menu>菜单时,可以在菜单上添加router属性,然后,各菜单项的index属性可配置为路径值,则点击菜单项时将跳转到此路径,例如:

<el-menu

      router

      default-active="2"

      class="el-menu-vertical-demo"

      background-color="#9ed3d7"

      text-color="#fff"

      active-text-color="#fff">

    <el-menu-item index="/sys-admin/index">

      <i class="el-icon-s-home"></i>

      <span slot="title">首页</span>

    </el-menu-item>

    <!-- 剩余其它代码 -->

使用Axios

在Vue CLI中,在使用Axios之前,需要先安装:

npm i axios -S

安装完成后,需要在main.js中添加配置:

import axios from 'axios';

Vue.prototype.axios = axios;

当使用Axios向其它远程服务器提交异步请求时,可能会出现CORS错误,即“跨域”的错误。

Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:8888' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

在Spring MVC项目中,当需要允许跨域访问时,需要在Spring MVC项目中自定义配置类,实现WebMvcConfigurer接口,重写其中的addCorsMapping()方法:

@Configuration

public class WebMvcConfiguration implements WebMvcConfigurer {



    @Override

    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")

                .allowCredentials(true)

                .allowedHeaders("*")

                .allowedMethods("*")

                .allowedOriginPatterns("*")

                .maxAge(3600);

    }

    

}

在Vue CLI项目中,当使用Axios时,需要使用this来引用axios,并且,在then()内部,只能使用箭头函数,不写使用匿名function函数,例如:

this.axios.post(url, this.ruleForm).then((response) => {

    console.log('服务器端响应的结果:' + response);

    console.log(response);

    if (response.data == 1) {

      console.log('登录成功');

      this.$message({

        message: '登录成功!',

        type: 'success'

      });

    } else if (response.data == 2) {

      console.log('登录失败,用户名错误!');

      this.$notify.error({

        title: '登录失败',

        message: '用户名不存在!'

      });

    } else {

      console.log('登录失败,密码错误!');

      this.$notify.error({

        title: '登录失败',

        message: '密码错误!'

      });

    }

  });

Spring框架

关于Spring框架

Spring框架主要解决了创建对象、管理对象的问题。

通过Spring创建对象

需要Spring创建对象,有2种做法:

  • @Bean方法
  • 组件扫描

关于@Bean方法

  • 在配置类中,自定义某个方法,其返回值类型就是你需要Spring创建对象的类型,在方法体中自行编写创建对象的代码,并且,在此方法上添加@Bean注解即可

关于组件扫描

  1. 通过@ComponentScan注解,可以开启组件扫描,并配置扫描的包
    • 在Spring Boot项目中,启动类上的@SpringBootApplication已经使用@ComponentScan作为元注解
    • 在Spring Boot项目中,默认的组件扫描的包就是启动类所在的包
    • 任何组件扫描,都会扫描指定的包及其子孙包
  2. 在组件类上,需要添加组件注解:基础的组件注解有:
    • @Component:通用组件注解
    • @Controller:建议添加在控制器类上
    • @Service:建议添加在处理业务逻辑的类上
    • @Repository:建议添加在数据访问层的类上
      • 在使用IntelliJ IDEA时,在Mybatis的Mapper接口上添加此注解,只是为了避免IntelliJ IDEA误判而已,并没有实质的作用
    • 以上4种注解,在Spring的解释范围内,是完全等效的,只是语义不同

另外,如果某个组件扫描范围内的类添加了@Configuration,也会被创建对象,添加此注解的类被视为“配置类”,与一般的组件不同,Spring框架会通过CGLib代理模式进行处理。

Spring管理的对象

Spring管理的对象,默认是单例的!并且,默认情况下,单例的对象都是默认加载的。

单例:单一实例,在某个时间点,此类的对象最多只有1个。

默认加载:加载Spring时,就会创建此类的对象,类似于单例模式中的饿汉式单例模式。

注意:Spring并没有使用单例模式,只是Spring管理的对象的表现与单例模式的特点是相同的。

使用@Scope注解,注解参数值配置为prototype(原型),可以使得Spring管理的对象不是单例的:

  • 使用组件扫描创建对象时,在组件类上添加@Scope("prototype")
  • 使用@Bean方法创建对象时,在@Bean方法上添加@Scope("prototype")

使用@Lazy注解,可以使得Spring管理的单例对象是懒加载的(第1次获取此对象时才创建对象):

  • 使用组件扫描创建对象时,在组件类上添加@Lazy
  • 使用@Bean方法创建对象时,在@Bean方法上添加@Lazy

Spring管理的对象的生命周期

被Spring管理的对象的类型,可以自定义2个生命周期方法,这2个方法会分别在“创建后”和“销毁前”被自动调用!

在自定义类中,可以自定义方法:

  • 访问权限:应该使用public
  • 返回值类型:void
  • 方法名称:自定义
  • 参数列表:仅可添加少量特定的类型

另外,在“创建后”的方法上,需要添加@PostConstruct注解,在“销毁前”的方法上,需要添加@PreDestroy注解,例如:

@PostConstruct

public void init() {

}



@PreDestroy

public void destroy() {

}

自动装配

Spring容器:Spring的本质是一个容器,它会将它创建的所有对象都管理在此容器中。

Spring Bean:每个被Spring创建的对象都是一个Spring Bean。

自动装配:当某个添加了自动装配注解的属性,或某个被Spring自动调用的方法的参数需要值时,Spring会自动尝试从容器中查找适合的Spring Bean,用于为此赋值。

通常,其表现就是在类的属性上添加@Autowired注解,则Spring会尝试自动为此属性赋值。

关于@Autowired的装配机制:

  • 首先,在Spring容器中查找匹配类型的Spring Bean的数量
    • 0个:取决于@Autowired注解的required属性
      • required = true:加载Spring时出现NoSuchBeanDefinitionException
      • required = false:放弃自动装配,则属性值为null
    • 1个:直接装配,且成功
    • 多个:将尝试根据名称来自动装配,要求被自动装配的属性名与Spring Bean的名称是匹配的,如果存在匹配的,则成功装配,否则,加载Spring时出现NoUniqueBeanDefinitionException
      • 关于名称匹配,可以是属性名改为某个Spring Bean名称,或在属性上添加@Qualifier注解来指定某个Spring Bean的名称

另外,在不使用@Autowired(含匹配的@Qualifier)的情况下,也可以在属性上添加@Resource注解来实现自动装配!

关于@Resource注解的装配机制:

  • 先尝试根据名称查找匹配的Spring Bean,且类型也匹配,则自动装配,如果没有匹配名称的Spring Bean,将尝试按照类型来装配,简单来说,是先根据名称,再根据类型的装配机制。

关于DI与IoC

IoCInversion OControl,控制反转,表示将对象的控制权(创建、管理)交给框架

DIDependency Injection,依赖注入,表现为给对象的依赖属性赋值

Spring AOP

AOP:Aspect Oriented Programming,面向切面编程

注意:AOP并不是Spring框架独有的技术或特点,即使没有使用Spring框架,也可以实现AOP,但是,Spring框架很好的支持了AOP,所以,通常会使用Spring来实现AOP。

在开发实践中,数据的处理流程大致是:

注册:客户端 <---(请求)---> Controller <------> Service <------> Mapper登录:客户端 <---(请求)---> Controller <------> Service <------> Mapper下单:客户端 <---(请求)---> Controller <------> Service <------> Mapper

假设,现在添加一个需求:统计每个业务(Service中的方法)的执行耗时。

在没有AOP的情况下,只能编辑每个Service方法,添加几乎相同代码来实现以上需求,并且,当需求发生变化时,每个Service方法可能需要再次调整。

使用AOP实现以上需求,大致需要:

创建切面类,并交给Spring框架管理

配置切面类中的方法在特定的点执行

在项目中添加spring-boot-starter-aop依赖。

在项目的根包下创建aop.TimerAspect类,在类上添加@Component和@Aspect注解

@Component
@Aspect
public class TimerAspect {
    // 【切面中的方法】
    // 访问权限:public
    // 返回值类型:当使用@Around时,使用Object类型
    // 方法名称:自定义
    // 参数列表:当使用@Around时,添加ProceedingJoinPoint类型的参数
    // 异常:当使用@Around时,抛出Throwable

    // @Before:在……之前
    // @After:在……之后
    // @AfterReturning:在返回之后
    // @AfterThrowing:在抛出异常之后
    // @Around:环绕

    // 关于以上注解,大致是:
    // @Before
    // try {
    //   pjp.proceed();
    //   @AfterReturning
    // } catch (Throwable e) {
    //   @AfterThrowing
    //   throw e;
    // } finally {
    //   @After
    // }

    // 注解中的表达式用于匹配某些方法,在表达式中,应该表示出“返回值类型 包.类.方法(参数列表)”
    // 以表达式中,可以使用星号(*)和2个连续的小数点(..)作为通配符
    // 其中,星号可以用于:返回值类型、包名、类名、方法名、参数
    // 而2个连续的小数点可以用于:包、参数
    // 星号只表示匹配1次,而2个连续的小数点表示匹配0~n次

    // 连接点:JoinPoint,表现为切面需要处理的某个方法,或其它的某种行为
    // 切入点:Point Cut,写在@Around等注解中的表达式
    // 通知:Advice,即@Around等注解及对应的代码
    // 切面:Aspect,囊括了切入点和通知的模块
    @Around("execution(* cn.tedu.csmall.product.service.impl.*.*(..))")
    public Object timer(ProceedingJoinPoint pjp) throws Throwable {
        // 【需求】统计每个Service方法的耗时
        log.debug("在某个Service的某个方法之前执行了……");

        long start = System.currentTimeMillis();

        // 执行(处理)连接点,即执行业务方法
        // 注意:必须获取调用proceed()方法的返回值
        // 注意:如果连接点是Service中的方法,调用proceed()时的异常必须声明抛出,不可以try...catch
        Object result = pjp.proceed();

        long end = System.currentTimeMillis();
        log.debug("当前切面匹配到的组件类:{}", pjp.getTarget());
        log.debug("当前切面匹配到的方法:{}", pjp.getSignature());
        log.debug("当前切面匹配到的方法的参数列表:{}", pjp.getArgs());
        log.debug("执行耗时:{}毫秒", end - start);

        // 注意:必须返回调用proceed()方法的结果
        return result;
    }

}

小结

关于Spring框架,你应该:

  • 理解Spring框架的作用
  • 掌握使得Spring框架创建对象的2种方式
    • @Bean方法
    • 组件扫描
  • 理解Spring框架管理的对象的作用域
    • 默认具有单例的特点
    • 在单例的状态下,默认是预加载的
  • 了解Spring框架管理的对象的生命周期方法
  • 理解Spring框架的自动装配的特点,理解@Autowired的装配机制
  • Spring AOP

另外,尚未涉及的部分:

  • 读取.properties配置文件,管理项目中的环境变量Environment

Spring MVC框架

关于Spring MVC框架

Spring MVC是建立在Spring框架基础之上的。

Spring MVC主要解决了接收请求、响应结果的问题。

基础配置

在Spring Boot项目中,添加spring-boot-starter-web依赖项,即可添加Spring MVC框架所需的依赖!

提示:如果使用的不是Spring Boot项目,当需要使用Spring MVC框架时,需要添加的依赖项是spring-webmvc

提示:只需要将原有的spring-boot-starter改为spring-boot-starter-web即可。

提示:在创建工程时,如果勾选了Web,本质上也是添加spring-boot-starter-web依赖项,另外,还会在src/main/resources下自动创建statictemplates文件夹。

一旦添加了spring-boot-starter-web,当启动Spring Boot项目时,会自动启动Tomcat,并将此项目部署到Tomcat上。

Spring Boot启动Tomcat时,默认占用8080端口,可以在application.properties中通过server.port属性来修改端口号,例如:

# 服务端口

server.port=9080

关于接收请求

需要自定义类,在类上添加@Controller / @RestController注解,则此类就是控制器类。

通常,建议在类上也添加@RequestMapping配置请求路径中的前缀部分。

在类中自定义处理请求的方法:

  • 注解:添加@RequestMapping系列注解来配置请求路径和某些参数
  • 访问权限:应该使用public
  • 返回值类型:在前后端分离的开发模式下,应该使用自定义的数据类型,例如JsonResult
  • 方法名称:自定义
  • 参数列表:当请求参数数量只有1个时,或少量参数且没有相关性,直接写,当请求参数数量超过1个且具有相关性时,应该封装为自定义的数据类型,并使用自定义的数
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值