Spring—分层的JavaSE(一站式)轻量级开源框架
Spring框架概述
1.1 什么是Spring
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
1.2 Spring的优点
对象由程序本身创建变为程序接受对象。Service和dao 实现分离 没有直接以来关系dao层改变 程序本身不需要改变
方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
spring工厂是用于生成bean
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
Spring框架—控制反转IoC)
控制反转指的就是将对象的创建权反转给(交给)了Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了,对象创建的控制权不是"使用者",而是"框架"或者"容器"。用更通俗的话来说,IoC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。
Spring 提供了以下两种不同类型的容器:
Spring BeanFactory 容器:它是最简单的容器,给 DI 提供了基本的支持
Spring ApplicationContext 容器:该容器添加了更多的企业特定的功能,当然我一般都是用这个。
IOC的实例,其实就是刚刚HelloWorld的实例,IOC就是通过配置文件,把我要需要创建的对象,也就是new的对象放到IOC容器里面,至于怎么放,就是我们在配置文件里面写的
<bean id="hello" class="com.java.bean.HelloWorld"></bean>
然后怎么从这个容器里面拿出来,就是通过ApplicationContext 的getBean通过bean的id获取到这个对象。
Spring框架—面向切面编程(AOP)
1 什么是AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
经典应用:事务管理、性能监视、安全检查、缓存 、日志等
Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
2 AOP实现原理
aop底层将采用代理机制进行实现。
接口 + 实现类 :spring采用 jdk 的动态代理Proxy。
实现类:spring 采用 cglib字节码增强。
3 AOP术语
1.target:目标类,需要被代理的类。例如:UserService
2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
3.PointCut 切入点:已经被增强的连接点。例如:addUser()
4.advice 通知/增强,增强代码。例如:after、before
5.Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
6.proxy 代理类
7.Aspect(切面): 是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
SpringMVC架构-基于Java实现MVC的轻量级Web框架。
1.什么是MVC
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
2.Spring MVC的特点:
轻量级,简单易学
高效 , 基于请求响应的MVC框架
与Spring兼容性好,无缝结合
约定优于配置
功能强大:RESTful、数据验证、格式化、本地化、主题等
简洁灵活
3.处理流程
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
我们假设请求的url为 : http://localhost:8080/SpringMVC/hello
如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
Handler让具体的Controller执行。
Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。最终视图呈现给用户。
FreeMarker
1 简介
FreeMarker是一款用java语言编写的模版引擎,它虽然不是web应用框架,但它很合适作为web应用框架的一个组件。
特点:
-
轻量级模版引擎,不需要Servlet环境就可以很轻松的嵌入到应用程序中
-
能生成各种文本,如html,xml,java,等
-
入门简单,它是用java编写的,很多语法和java相似
工作原理:
项目创建流程
第一步:创建一个maven项目导入 FreeMarker jar 包
第二步:创建目录templates,并创建一个 FreeMarker模版文件 hello.ftl
第三步:创建一个运行FreeMarker模版引擎的 FreeMarkerDemo.java 文件
第四步:运行main方法后刷新项目
pom.xml 文件 ,maven 项目核心文件,管理 jar 包。
springboot
1.什么是SpringBoot?
SpringBoot就是为了解决Spring缺点而生的,主要是简化了使用 Spring 的难度,节省了繁重的配置,开发者能够快速上手。
SpringBoot的核心功能有两个,起步依赖,自动配置,也就是他的默认配置;
起步依赖就是将具备某种功能的坐标打包到一起, 并解决了Spring的jar包冲突问题。
自动配置就是SpringBoot在底层给我们自动做了一些配置,所以springboot项目不编写配置文件也可以正常运行,但是根据我们的具体开发需要修改SpringBoot自动配置的默认值;
2.Spring Boot 优点非常多,如:
独立运行,使用java -jar xx.jar即可运行.
简化配置
自动配置
无代码生成和XML配置,通过注解来实现
内嵌服务容器.
2.SpringBoot的核心功能
核心功能:
1.1: springboot项目为独立运行的spring项目,使用java -jar xx.jar即可运行.
1.2: 内嵌servlet容器(可以选择内嵌: tomcat ,jetty等服务器.).
1.3: 提供了starter的pom 配置 简化了 maven的配置.
1.4: 自动配置spring容器中的bean.当不满足实际开发场景,可自定义bean的自动化配置.
1.5: 准生产的应用监控(基于: ssh , http , telnet 对服务器运行的项目进行监控.).
1.6: springboot无需做出xml配置,也不是通过代码生成来实现(通过条件注解.).
使用优点:
1.快速搭建项目,
2,与主流框架集成无需配置集成.
3.内嵌服务容器.
4.具有应用监控.
5.开发部署方便,后期与云计算平台集成方便(docket).
Spring Boot 项目文件介绍
1、解析 pom.xml 文件:
让我们来看看默认生成的 pom.xml 文件中到底有些什么:
//头信息
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
//在 maven 中,根据 groupId、artifactId、version 组合成 groupId:artifactId:version
//来唯一识别一个 jar 包。
<groupId>com.xpwi</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
//这个标签是在配置 Spring Boot 的父级依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
//该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、Spring Boot 的配置文件:
Spring Boot 使用一个全局的配置文件 application.properties 或 application.yml,放置在【src/main/resources】目录或者类路径的 /config 下。
Spring Boot 不仅支持常规的 properties 配置文件,还支持 yaml 语言的配置文件。yaml 是以数据为中心的语言,在配置数据的时候具有面向对象的特征。
Spring Boot 的全局配置文件的作用是对一些默认配置的配置值进行修改。
可以使用 @Value 来获取配置属性
.yml
2).yml
app:
user:
name: javastack
另外,.yml 格式不支持 @PropertySource 注解导入配置。
3.SpringBoot创建过程
1.创建maven过程
2.导入起步依赖
3.创建引导类
1.成为引导类:@SpringBootApplication
2.运行引导类:SpringApplication.run(引导类的字节码对象)
4.创建controller
1.在引导类的同级目录下
2.在引导类的同级的子目录下
4.springboot中的核心启动主函数(main函数)的作用.用到哪些注解.注解的作用.
@SpringBootApplication
public class SpringBoot1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot1Application.class, args);
}
}
该主函数: 主要启动springboot框架.用于加载容器和Spring等默认组件.
用到核心注解: @SpringBootApplication . 作用:用于标识声明一个springboot框架容器.
启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。
5.SpringBoot 中常用注解
1.引导类的@SpringBootApplication
2.@Controller 处理http请求
3.@RestController:
Spring4之后新加入的注解,原来返回json需要@ResponseBody和@Controller配合。现在只需要@RestContrller
4.@RequestMapping 配置url映射
5.@ConfigurationProperties(prefix=“配置文件中的 key 的前缀”)可以将配置文件中的配置自动
与实体进行映射
6.@Autowired
6.springboot的静态页放在哪里?
首先,在 Spring Boot 中,默认情况下,一共有5个位置可以放静态资源,五个路径分别是如下5个:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/
这个是系统默认配置,如果我们并不想将资源放在系统默认的这五个位置上,也可以自定义静态资源位置和映射,自定义的方式也有两种,可以通过 application.properties 来定义,也可以在 Java 代码中来定义。
在配置文件中定义的方式比较简单,如下:
spring.resources.static-locations=classpath:/
spring.mvc.static-path-pattern=/**
当然,在Spring Boot中我们也可以通过 Java代码来自定义,方式和 Java 配置的 SSM 比较类似,如下
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/aaa/");
}
}
7.控制层编写
在SpringMVC中, Controller层主要工作:从HTTP请求中获取信息,提取参数,并将其分发给不同的处理服务(service层),并向前端返回service层处理后的数据,客户端发送来的请求Request中的URL就映射到Controller层的一个方法。
Spring Boot 的 MVC 支持主要来介绍实际项目中最常用的几个注解,包括 @RestController、 @RequestMapping、@PathVariable、@RequestParam 以及 @RequestBody。主要介绍这几个注解常用的使用方式和特点。
我们来编写一个简单的Controller返回一个单间的json字符串,如下:
@Controller
@RequestMapping(value = "/hello")
public class HelloController {
@RequestMapping("/helloweb")
public String hello(ModelMap modelMap){
//向模板中添加属性
modelMap.put("hello","helloweb");
// return模板文件的名称,对应src/main/resources/templates/index.html
return "index";
}
}
此处注意的一点是,一定要使用@Controller这个注解才可以跳转到对应的模板中,这个注解等同于使用@ResponseBody和@RestController,大家在使用时一定要注意。
8.模板
前端页面使用Thymeleaf模板页面和静态页面对比:
Thymeleaf模板:先到controller的方法,在方法里查出数据,然后将查出的数据放到model里面,最后返回页面
静态页面:先到页面,页面到页面可以带有参数,然后在第二张页面用ajax进行请求controller的方法,获取数据,将数据返回到页面,进行渲染(常用这种方法)
为什么要使用模板
如果系统的某一个页面需要返回大量的数据,而且该页面经常被大量请求访问,那么该页面的数据渲染问题就会变成系统性能的短板,同时大量的请求会对数据库造成极大的压力。
这个时候,我们通过后端获取数据,然后响应前端渲染数据的方法就很难解决这个问题。
使用模板省去了系统请求后端的和前端渲染数据的时间,大大提高了系统的访问效率。
如何创建模板
我们在src/main/resources/templates目录下创建一个叫index.html的文件,访问变量使用th:进行访问;
<td><a th:href="'/goods/to_detail/'+${goods.id}">详情</a></td>
在这里需要进行一下说明:
1>这个配置不是必须的,因为SpringBoot它自身有相关的默认配置,我们的配置会覆盖相关的默认配置
2>我们在进行页面返回的时候,页面是默认储存在resource文件下的templates文件里面的。
3>使用Thymeleaf默认页面就是HTML页面,所以这是非常方便的。
8.Spring Boot整合MyBatis
引入依赖
Spring Boot 整合 MyBatis 的第一步,就是在项目的 pom.xml 中引入 mybatis-spring-boot-starter 的依赖,示例代码如下。
<!--引入 mybatis-spring-boot-starter 的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
配置 MyBatis
在 Spring Boot 的配置文件(application.properties/yml)中对 MyBatis 进行配置,例如指定 mapper.xml 的位置、实体类的位置、是否开启驼峰命名法等等,示例代码如下。
mybatis:
# 指定 mapper.xml 的位置
mapper-locations: classpath:mybatis/mapper/*.xml
#扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名
type-aliases-package: net.biancheng.www.bean
configuration:
#默认开启驼峰命名法,可以不用设置该属性
map-underscore-to-camel-case: true
创建实体类、创建 Mapper 接口、创建 Mapper 映射文件
使用 Mapper 进行开发时,需要遵循以下规则:
1.mapper 映射文件中 namespace 必须与对应的 mapper 接口的完全限定名一致。
2.mapper 映射文件中 statement 的 id 必须与 mapper 接口中的方法的方法名一致
3.mapper 映射文件中 statement 的 parameterType 指定的类型必须与 mapper 接口中方法的参数类型一致。
4.mapper 映射文件中 statement 的 resultType 指定的类型必须与 mapper 接口中方法的返回值类型一致。
9.springboot 整合 redis
Redis
基于内存进行存储,支持key-value的存储形式,底层是用C语言进行编写的
基于key-value形式的数据字典,结构简单,没有数据表的概念,直接用键值对形式完成数据的管理。
1、在pom.xml 增加依赖如下:
<!-- 引入 redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
2、资源文件application.properties中增加Redis相关配置
############################################################
# REDIS 配置
############################################################
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=2
spring.redis.timeout=6000
3、封装Json工具类
这个工具类比较简单,封装操作redisTemplate的实现类。这个工具类只是简单的封装了StringRedisTemplate,其他相关的数据类型大家可以根据自己的需要自行扩展。
10.springboot整合shiro
shiro主要有三大功能模块:
- Subject:主体,一般指用户。
- SecurityManager:安全管理器,管理所有Subject,可以配合内部安全组件。(类似于SpringMVC中的DispatcherServlet)
- Realms:用于进行权限信息的验证,一般需要自己实现。
配置ShiroConfig
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
bean.setLoginUrl("/login");
bean.setSuccessUrl("/index");
Map<String, String> map = new LinkedHashMap<>();
//匿名访问
map.put("/doLogin", "anon");
//登录后访问
map.put("/**", "authc");
//定义拦截规则
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
11.Vue与Springboot的简单整合
安装vue和vue-cli
npm install vue
npm install -g @vue/cli
npm install -g @vue/cli-init
模板
<!--修改模板如下-->
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<el-button type="primary" @click="visible = true">Button</el-button>
<el-dialog :visible.sync="visible" title="Hello world">
<p>Try Element</p>
</el-dialog>
<br><br>
<el-button type="primary" @click="getRequest">Get测试</el-button>
<el-button type="primary" @click="postRequest">Post测试</el-button>
<h2>Ecosystem</h2>
</div>
</template>
<!--在data return方法内增加-->
Axios请求测试
发送get请求
this.$axios.get('/hello')
.then(function(response) {
console.log(response);
})
.catch(function(err) {
console.log(err);
});
发送post请求
<!-- axios的表单提交,Content-Type默认为application/json;charset=UTF-8 -->
this.$axios.post('/sayHello',data,{headers:{'Content-Type':'application/x-www-form-urlencoded'}})
.then(function(response) {
console.log(response);
})
.catch(function(err) {
console.log(err);
});