9、JAVAEE框架
9.1 spring框架
9.2 springMVC框架
9.3 Mybatis 框架
9.4 springboot简介
9.5 微服务
1、Spring体系结构组成
Date Access/Integration 数据访问/集成
JDBC模块提供了删除冗余的JDBC相关编码的JDBC抽象层。
ORM模块为流行的对象关系映射API,包括JPA,JDO,Hibernate和iBatis,提供了集成层。
OXM模块提供了抽象层,它支持对JAXB,Castor,XMLBeans,JiBX和XStream的对象/XML映射实现。
Java消息服务JMS模块包含生产和消费的信息的功能。
事务模块Transactions为实现特殊接口的类及所有的POJO支持编程式和声明式事务管理。
Web(MVC/Remoting远程处理)
Web模块提供了基本的面向web的集成功能,例如多个文件上传的功能和使用servlet监听器和面向web应用程序的上下文来初始化IoC容器。
Web-MVC模块包含Spring的模型-视图-控制器(MVC),实现了web应用程序。
Web-Socket模块为WebSocket-based提供了支持,而且在web应用程序中提供了客户端和服务器端之间通信的两种方式。
Web-Portlet模块提供了在portlet环境中实现MVC,并且反映了Web-Servlet模块的功能。
AOP模块提供了面向切面的变成实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能。
Aspects模块提供了与AspectJ的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。
Instrumentation模块在一定的应用服务器中提供了类instrumentation的支持和类加载器的实现。
Messaging模块为STOMP提供了支持作为在应用程序中WebSocket子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自WebSocket客户端的STOMP信息。
Core Container 核心容器
Beans模块提供BeanFactory,它是一个工厂模式的复杂实现。
Core模块提供了框架的基本组成部分,包括IoC和依赖注入功能。
Context上下文模块建立在由Core和Beans模块提供的坚实基础上,它是访问定义和配置任何对象的媒介。ApplicationContext接口是Context模块的重点。
SpEL表达式语言模块在运行时提供了查询和操作一个对象图的强大的表达式语言。
Test测试模块支持对具有JUnit或TestNG框架的Spring组件的测试。
2、Spring的理解
首先,spring是一个开源框架,Spring为简化企业级应用开发而生,使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。
Spring主要核心是:
(1)控制反转(IOC):传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象,而在Spring开发模式中,Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。实例化一个java对象有三种方式:使用类构造器,使用静态工厂方法,使用实例工厂方法,当使用spring时我们就不需要关心通过何种方式实例化一个对象,spring通过控制反转机制自动为我们实例化一个对象。
(2)依赖注入(DI):Spring使用Java Bean对象的Set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。
(3)面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。
IoC 和 DI的区别?
IoC 控制反转,指将对象的创建权,反转到Spring容器 , DI 依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入
spring支持构造器注入和setter方法注入
构造器注入,通过 <constructor-arg> 元素完成注入
setter方法注入, 通过<property> 元素完成注入【开发中常用方式】
在Spring中,所有管理的对象都是JavaBean对象,而BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在一般使用ApplicationContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展。
3、Spring Bean生命周期
1.Spring容器 从XML 文件中读取Bean的定义,并实例化Bean。
2.Spring根据Bean的定义填充所有的属性。
3.如果Bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
4.如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
5.如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
6.如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
7.如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
8.如果bean实现了 DisposableBean,它将调用destroy()方法。
注意:
有两个重要的bean 生命周期方法,第一个是setup() , 它是在容器加载bean的时候被调用。第二个方法是 teardown() 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性init-method和destroy-method。使用它们你可以自己定制初始化和注销方法。它们也有相应的注解@PostConstruct和@PreDestroy。
4、Spring 中的设计模式
1.代理模式—Spring中两种代理方式,若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理,若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
2.单例模式—在spring配置文件中定义的bean默认为单例模式。
3.模板方法模式—用来解决代码重复的问题。
比如: RestTemplate, JmsTemplate, JpaTemplate。
4.前端控制器模式—Srping提供了DispatcherServlet来对请求进行分发。
5.视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
6.依赖注入—贯穿于BeanFactory/ApplicationContext接口的核心理念。
7.工厂模式—在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。Spring中使用BeanFactory用来创建对象的实例。
5、Spring注解
Spring在2.5版本以后开始支持用注解的方式来配置依赖注入。可以用注解的方式来替代XML方式的bean描述,可以将bean描述转移到组件类的内部,只需要在相关类上、方法上或者字段声明上使用注解即可。注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式。如果你想要在你的应用程序中使用关于注解的方法的话,请参考如下的配置。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
在 <context:annotation-config/>标签配置完成以后,就可以用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。
几种比较重要的注解类型:
@Component :标识了一个受Spring管理的组件,泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
@Respository: 标识持久层,数据访问组件,即DAO组件
@Service: 标识业务层组件
@Controller :标识表现层,控制层组件
(1)@RequestMapping
@RequestMapping 是用来处理请求地址映射的注解,可用于类或方法上。用在类上,表示类中所有的响应的方法都是以该地址作为父路径来访问,用在方法上表示该方法的访问的路径;两者结合起来的访问的路径为完整的访问某个方法的路径。
@RequestMapping注解的属性:
value:指定请求的实际的地址,指定的地址可以是URI Template模式;
method:指定访问的方法
consumes:指定处理请求的内容类型,比如aplication/json;text/html
produces:指定返回的内容的类型
params:指定request中必须包含某些参数值时,才让该方法处理请求
headers:指定request中必须包含指定的header值,才能让该方法处理请求
@Resource和@Autowired
@Resource和@Autowired都是做bean的注入时使用,都可以写在字段上,或者是setter方法上
@Autowired注解是按照类型(byType)装配依赖对象(由Spring提供)
如果在此基础上想通过byName来装配,可以结合@Qualifier注解来一起使用。
@Resource默认按照byName自动注入
@Resource有两个重要的属性,name和type
@Resource如果写属性name,则按照byName来装配,如果属性为type,则按照byType来装配,不写按照默认的方式来装配(byName)
6、Spring事务
Spring支持两种类型的事务管理:
1.编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
2.声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
Spring事务配置示例(使用tx标签配置的拦截器)
<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置Advice通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 配置切点切面 -->
<aop:config>
<aop:pointcut id="interceptorPointCuts"
expression="execution(* com.bluesky.spring.dao.*.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="interceptorPointCuts" />
</aop:config>
事务:什么是事务?
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。
数据库事务必须具备ACID特性,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写。
原子性:指整个数据库事务是不可分割的工作单位。只有使据库中所有的操作执行成功,才算整个事务成功;事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。
一致性:指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款总额为2000元。
隔离性:指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
持久性:指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
事务的(ACID)特性是由关系数据库管理系统(RDBMS,数据库系统)来实现的。数据库管理系统采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所做的更新,如果某个事务在执行过程中发生错误,就可以根据日志,撤销事务对数据库已做的更新,使数据库退回到执行事务前的初始状态。
数据库管理系统采用锁机制来实现事务的隔离性。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
在@Transactional注解中,可以propagation属性用来配置事务传播,支持7种不同的传播机制:
REQUIRED:业务方法需要在一个事务中运行,如果方法运行时,已处在一个事务中,那么就加入该事务,否则自己创建一个新的事务。这是spring默认的传播行为。
隔离级别:
Read uncommitted
读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据
Read committed
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
Repeatable read
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
这个默认隔离级别是与具体的数据库相关的
采取的是具体数据库的默认隔离级别
不同的数据库是不一样的
9.2 springMVC框架
9.2.1 SpringMVC的执行流程
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
- 执行处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户
9.2.3、SpringMVC的注解
1.@Controller
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。
2.@RequestMapping
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
3.@Resource和@Autowired
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
相同点:两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。ssss
不同点:
@Autowired为Spring提供的注解,需要导入包
org.springframework.beans.factory.annotation.Autowired;
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
public class TestServiceImpl {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
2) @Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。
4.@ModelAttribute和 @SessionAttributes
@ModelAttribute该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。
@SessionAttributes即将值放到session作用域中,写在class上面。
5.@PathVariable
用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。
6.@requestParam
@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter("name"),它有三个常用参数:defaultValue = "0", required = false, value = "isApp";defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。
7.@ResponseBody
作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
8.@Component
相当于通用的注解,当不知道一些类归到哪个层时使用,但是不建议。
9.@Repository
用于注解dao层,在daoImpl类上面注解。
9.3 MYbatis框架
1、Mybatis的理解
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
Mybatis的优点:
1、简单易学。mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar加配置几个sql映射文件,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现;
2、灵活。mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多;
3、解除sql与程序代码的耦合。通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性;
4、提供映射标签,支持对象与数据库的orm字段关系映射;
5、提供对象关系映射标签,支持对象关系组建维护;
6、提供xml标签,支持编写动态sql。
2、Mybatis的配置
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。文档的顶层结构如下:
configuration 配置
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
settings设置
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
设置参数 | 描述 | 有效值 | 默认值 |
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关。 | true|false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 | true|false | false |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true|false | false |
typeAliases类型命名
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
environments配置环境
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。
不过要记住:尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。
所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:每个数据库对应一个 SqlSessionFactory 实例。
为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。
transactionManager事务管理器
如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。
这两种事务管理器类型都不需要任何属性。它们不过是类型别名,换句话说,你可以使用 TransactionFactory 接口的实现类的完全限定名或类型别名代替它们。
mappers映射器
告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。
3、Mybatis执行流程
- mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
- 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
- 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
- Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
4、Mybatis缓存
一级缓存:Mybatis的一级缓存的作用域是session,当openSession()后,如果执行相同的SQL(相同语句和参数),Mybatis不进行执行SQL,而是从缓存中命中返回。
二级缓存:Mybatis的二级缓存的作用域是一个mapper的namespace,同一个namespace中查询sql可以从缓存中命中。二级缓存是可以跨session的。
9.4 springboot简介
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的开发过程。
Spring Boot让我们的Spring应用变的更轻量化。比如:你可以仅仅依靠一个Java类来运行一个Spring应用。你也可以打包你的应用为jar并通过使用java -jar来运行你的Spring Web应用。
Spring Boot的主要优点:
- 为所有Spring开发者更快的入门
- 简化项目配置
- 内嵌式容器简化Web项目
- springboot整合的框架统一管理版本,不会存在版本冲突
- springcloud基于springboot开发
Spring Boot 是微服务中最好的 Java 框架.
问题一 Spring Boot、Spring MVC 和 Spring 有什么区别?
SpringFrame
SpringFramework 最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就是 IOC 控制反转。
当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。
SpringMVC
Spring MVC 提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。
SpringBoot
Spring 和 SpringMVC 的问题在于需要配置大量的参数。
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
问题二 什么是自动配置?
Spring 和 SpringMVC 的问题在于需要配置大量的参数。
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
我们能否带来更多的智能?当一个 MVC JAR 添加到应用程序中的时候,我们能否自动配置一些 beans?
Spring 查看(CLASSPATH 上可用的框架)已存在的应用程序的配置。在此基础上,Spring Boot 提供了配置应用程序和框架所需要的基本配置。这就是自动配置。
问题三 什么是 Spring Boot Stater ?
启动器是一套方便的依赖没描述符,它可以放在自己的程序中。你可以一站式的获取你所需要的 Spring 和相关技术,而不需要依赖描述符的通过示例代码搜索和复制黏贴的负载。
例如,如果你想使用 Sping 和 JPA 访问数据库,只需要你的项目包含 spring-boot-starter-data-jpa 依赖项,你就可以完美进行。
问题四 你能否举一个例子来解释更多 Staters 的内容?
让我们来思考一个 Stater 的例子 -Spring Boot Stater Web。
如果你想开发一个 web 应用程序或者是公开 REST 服务的应用程序。Spring Boot Start Web 是首选。让我们使用 Spring Initializr 创建一个 Spring Boot Start Web 的快速项目。
Spring Boot Start Web 的依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
下面的截图是添加进我们应用程序的不同的依赖项
依赖项可以被分为
Spring - core,beans,context,aop
Web MVC - (Spring MVC)
Jackson - for JSON Binding
Validation - Hibernate,Validation API
Enbedded Servlet Container - Tomcat
Logging - logback,slf4j
任何经典的 Web 应用程序都会使用所有这些依赖项。Spring Boot Starter Web 预先打包了这些依赖项。
作为一个开发者,我不需要再担心这些依赖项和它们的兼容版本。
问题五 Spring Boot 还提供了其它的哪些 Starter Project Options?
Spring Boot 也提供了其它的启动器项目包括,包括用于开发特定类型应用程序的典型依赖项。
spring-boot-starter-web-services - SOAP Web Services
spring-boot-starter-web - Web 和 RESTful 应用程序
spring-boot-starter-test - 单元测试和集成测试
spring-boot-starter-jdbc - 传统的 JDBC
spring-boot-starter-hateoas - 为服务添加 HATEOAS 功能
spring-boot-starter-security - 使用 SpringSecurity 进行身份验证和授权
spring-boot-starter-data-jpa - 带有 Hibeernate 的 Spring Data JPA
spring-boot-starter-data-rest - 使用 Spring Data REST 公布简单的 REST 服务
问题六 Spring 是如何快速创建产品就绪应用程序的?
Spring Boot 致力于快速产品就绪应用程序。为此,它提供了一些譬如高速缓存,日志记录,监控和嵌入式服务器等开箱即用的非功能性特征。
spring-boot-starter-actuator - 使用一些如监控和跟踪应用的高级功能
spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat - 选择您的特定嵌入式 Servlet 容器
spring-boot-starter-logging - 使用 logback 进行日志记录
spring-boot-starter-cache - 启用 Spring Framework 的缓存支持
###Spring2 和 Spring5 所需要的最低 Java 版本是什么?
Spring Boot 2.0 需要 Java8 或者更新的版本。Java6 和 Java7 已经不再支持。
推荐阅读:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0.0-M1-Release-Notes
问题七 创建一个 Spring Boot Project 的最简单的方法是什么?
Spring Initializr是启动 Spring Boot Projects 的一个很好的工具。
就像上图中所展示的一样,我们需要做一下几步:
登录 Spring Initializr,按照以下方式进行选择:
选择 com.in28minutes.springboot 为组
选择 studet-services 为组件
选择下面的依赖项
Web
Actuator
DevTools
点击生 GenerateProject
将项目导入 Eclipse。文件 - 导入 - 现有的 Maven 项目
问题八 Spring Initializr 是创建 Spring Boot Projects 的唯一方法吗?
不是的。
Spring Initiatlizr 让创建 Spring Boot 项目变的很容易,但是,你也可以通过设置一个 maven 项目并添加正确的依赖项来开始一个项目。
在我们的 Spring 课程中,我们使用两种方法来创建项目。
第一种方法是 start.spring.io 。
另外一种方法是在项目的标题为“Basic Web Application”处进行手动设置。
手动设置一个 maven 项目
这里有几个重要的步骤:
在 Eclipse 中,使用文件 - 新建 Maven 项目来创建一个新项目
添加依赖项。
添加 maven 插件。
添加 Spring Boot 应用程序类。
到这里,准备工作已经做好!
问题九 为什么我们需要 spring-boot-maven-plugin?
spring-boot-maven-plugin 提供了一些像 jar 一样打包或者运行应用程序的命令。
spring-boot:run 运行你的 SpringBooty 应用程序。
spring-boot:repackage 重新打包你的 jar 包或者是 war 包使其可执行
spring-boot:start 和 spring-boot:stop 管理 Spring Boot 应用程序的生命周期(也可以说是为了集成测试)。
spring-boot:build-info 生成执行器可以使用的构造信息。
问题十 如何使用 SpringBoot 自动重装我的应用程序?
使用 Spring Boot 开发工具。
把 Spring Boot 开发工具添加进入你的项目是简单的。
把下面的依赖项添加至你的 Spring Boot Project pom.xml 中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
重启应用程序,然后就可以了。
同样的,如果你想自动装载页面,有可以看看 FiveReload
http://www.logicbig.com/tutorials/spring-framework/spring-boot/boot-live-reload/.
在我测试的时候,发现了 LiveReload 漏洞,如果你测试时也发现了,请一定要告诉我们。
问题十一 什么是嵌入式服务器?我们为什么要使用嵌入式服务器呢?
思考一下在你的虚拟机上部署应用程序需要些什么。
第一步: 安装 Java
第二部: 安装 Web 或者是应用程序的服务器(Tomat/Wbesphere/Weblogic 等等)
第三部: 部署应用程序 war 包
如果我们想简化这些步骤,应该如何做呢?
让我们来思考如何使服务器成为应用程序的一部分?
你只需要一个安装了 Java 的虚拟机,就可以直接在上面部署应用程序了,
是不是很爽?
这个想法是嵌入式服务器的起源。
当我们创建一个可以部署的应用程序的时候,我们将会把服务器(例如,tomcat)嵌入到可部署的服务器中。
例如,对于一个 Spring Boot 应用程序来说,你可以生成一个包含 Embedded Tomcat 的应用程序 jar。你就可以想运行正常 Java 应用程序一样来运行 web 应用程序了。
嵌入式服务器就是我们的可执行单元包含服务器的二进制文件(例如,tomcat.jar)。
问题十二 如何在 Spring Boot 中添加通用的 JS 代码?
在源文件夹下,创建一个名为 static 的文件夹。然后,你可以把你的静态的内容放在这里面。
例如,myapp.js 的路径是 resources\static\js\myapp.js
你可以参考它在 jsp 中的使用方法
<csript src="/js/myapp.js"></script>
错误:HAL browser gives me unauthorized error - Full authenticaition is required to access this resource.
该如何来修复这个错误呢?
{
"timestamp": 1488656019562,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource.",
"path": "/beans"
}
两种方法:
方法 1:关闭安全验证
application.properties
management.security.enabled:FALSE
方法二:在日志中搜索密码并传递至请求标头中
问题十三 什么是 Spring Date?
来自://projects.spring.io/spring- data/
Spring Data 的使命是在保证底层数据存储特殊性的前提下,为数据访问提供一个熟悉的,一致性的,基于 Spring 的编程模型。这使得使用数据访问技术,关系数据库和非关系数据库,map-reduce 框架以及基于云的数据服务变得很容易。
为了让它更简单一些,Spring Data 提供了不受底层数据源限制的 Abstractions 接口。
下面来举一个例子
interface TodoRepository extends CrudRepository<Todo, Long> {
你可以定义一简单的库,用来插入,更新,删除和检索代办事项,而不需要编写大量的代码。
问题十四 什么是 Spring Data REST?
Spring Data TEST 可以用来发布关于 Spring 数据库的 HATEOAS RESTful 资源。
下面是一个使用 JPA 的例子
@RepositoryRestResource(collectionResourceRel = "todos", path = "todos")
public interface TodoRepository
extends PagingAndSortingRepository<Todo, Long> {
不需要写太多代码,我们可以发布关于 Spring 数据库的 RESTful API。
下面展示的是一些关于 TEST 服务器的例子
POST
URL:http://localhost:8080/todos
Use Header:Content-Type:Type:application/json
Request Content
代码如下
{
"user": "Jill",
"desc": "Learn Hibernate",
"done": false
}
响应内容
{
"user": "Jill",
"desc": "Learn Hibernate",
"done": false,
"_links": {
"self": {
"href": "http://localhost:8080/todos/1"
},
"todo": {
"href": "http://localhost:8080/todos/1"
}
}
}
响应包含新创建资源的 href。
问题十五 path=”users”, collectionResourceRel=”users” 如何与 Spring Data Rest 一起使用?
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRestRepository extends
PagingAndSortingRepository<User, Long>
path- 这个资源要导出的路径段。
collectionResourceRel- 生成指向集合资源的链接时使用的 rel 值。在生成 HATEOAS 链接时使用。
问题十六 当 Spring Boot 应用程序作为 Java 应用程序运行时,后台会发生什么?
如果你使用 Eclipse IDE,Eclipse maven 插件确保依赖项或者类文件的改变一经添加,就会被编译并在目标文件中准备好!在这之后,就和其它的 Java 应用程序一样了。
当你启动 java 应用程序的时候,spring boot 自动配置文件就会魔法般的启用了。
当 Spring Boot 应用程序检测到你正在开发一个 web 应用程序的时候,它就会启动 tomcat。
问题十七 我们能否在 spring-boot-starter-web 中用 jetty 代替 tomcat?
在 spring-boot-starter-web 移除现有的依赖项,并把下面这些添加进去。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
问题十八 如何使用 Spring Boot 生成一个 WAR 文件?
推荐阅读:
https://spring.io/guides/gs/convert-jar-to-war/
下面有 spring 说明文档直接的链接地址:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging
问题十九 如何使用 Spring Boot 部署到不同的服务器?
你需要做下面两个步骤:
在一个项目中生成一个 war 文件。
将它部署到你最喜欢的服务器(websphere 或者 Weblogic 或者 Tomcat and so on)。
第一步:这本入门指南应该有所帮助:
https://spring.io/guides/gs/convert-jar-to-war/
第二步:取决于你的服务器。
问题二十 RequestMapping 和 GetMapping 的不同之处在哪里?
RequestMapping 具有类属性的,可以进行 GET,POST,PUT 或者其它的注释中具有的请求方法。
GetMapping 是 GET 请求方法中的一个特例。它只是 ResquestMapping 的一个延伸,目的是为了提高清晰度。
问题二十一 为什么我们不建议在实际的应用程序中使用 Spring Data Rest?
我们认为 Spring Data Rest 很适合快速原型制造!在大型应用程序中使用需要谨慎。
通过 Spring Data REST 你可以把你的数据实体作为 RESTful 服务直接发布。
当你设计 RESTful 服务器的时候,最佳实践表明,你的接口应该考虑到两件重要的事情:
你的模型范围。
你的客户。
通过 With Spring Data REST,你不需要再考虑这两个方面,只需要作为 TEST 服务发布实体。
这就是为什么我们建议使用 Spring Data Rest 在快速原型构造上面,或者作为项目的初始解决方法。对于完整演变项目来说,这并不是一个好的注意。
问题二十二 在 Spring Initializer 中,如何改变一个项目的包名字?
好消息是你可以定制它。点击链接“转到完整版本”。你可以配置你想要修改的包名称!
问题二十三 可以配置 application.propertierde 的完整的属性列表在哪里可以找到?
这里是完整的指南:
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
问题二十四 JPA 和 Hibernate 有哪些区别?
简而言之
JPA 是一个规范或者接口
Hibernate 是 JPA 的一个实现
当我们使用 JPA 的时候,我们使用 javax.persistence 包中的注释和接口时,不需要使用 hibernate 的导入包。
我们建议使用 JPA 注释,因为哦我们没有将其绑定到 Hibernate 作为实现。后来(我知道 - 小于百分之一的几率),我们可以使用另一种 JPA 实现。
问题二十五 业务边界应该从哪一层开始?
我们建议在服务层管理义务。商业业务逻辑在商业层或者服务层,与此同时,你想要执行的业务管理也在该层。
问题二十六 使用 Spring Boot 启动连接到内存数据库 H2 的 JPA 应用程序需要哪些依赖项?
在 Spring Boot 项目中,当你确保下面的依赖项都在类路里面的时候,你可以加载 H2 控制台。
web 启动器
h2
jpa 数据启动器
其它的依赖项在下面:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
需要注意的一些地方:
一个内部数据内存只在应用程序执行期间存在。这是学习框架的有效方式。
这不是你希望的真是世界应用程序的方式。
在问题“如何连接一个外部数据库?”中,我们解释了如何连接一个你所选择的数据库。
问题二十七 如何不通过任何配置来选择 Hibernate 作为 JPA 的默认实现?
因为 Spring Boot 是自动配置的。
下面是我们添加的依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
spring-boot-stater-data-jpa 对于 Hibernate 和 JPA 有过渡依赖性。
当 Spring Boot 在类路径中检测到 Hibernate 中,将会自动配置它为默认的 JPA 实现。
问题二十八 指定的数据库连接信息在哪里?它是如何知道自动连接至 H2 的?
这就是 Spring Boot 自动配置的魔力。
来自:https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html
Spring Boot auto-configuration 试图自动配置你已经添加的基于 jar 依赖项的 Spring 应用程序。比如说,如果 HSQLDBis 存在你的类路径中,并且,数据库连接 bean 还没有手动配置,那么我们可以自动配置一个内存数据库。
进一步的阅读:
http://www.springboottutorial.com/spring-boot-auto-configuration
问题二十九 我们如何连接一个像 MSSQL 或者 orcale 一样的外部数据库?
让我们以 MySQL 为例来思考这个问题:
第一步 - 把 mysql 连接器的依赖项添加至 pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
第二步 - 从 pom.xml 中移除 H2 的依赖项
或者至少把它作为测试的范围。
<!--
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
-->
第三步 - 安装你的 MySQL 数据库
更多的来看看这里 -https://github.com/in28minutes/jpa-with-hibernate#installing-and-setting-up-mysql
第四步 - 配置你的 MySQL 数据库连接
配置 application.properties
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://localhost:3306/todo_example
spring.datasource.username=todouser
spring.datasource.password=YOUR_PASSWORD
第五步 - 重新启动,你就准备好了!
就是这么简单!
问题三十 Spring Boot 配置的默认 H2 数据库的名字是上面?为什么默认的数据库名字是 testdb?
在 application.properties 里面,列出了所有的默认值
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
找到下面的属性
spring.datasource.name=testdb # Name of the datasource.
如果你使用了 H2 内部存储数据库,它里面确定了 Spring Boot 用来安装你的 H2 数据库的名字。
问题三十一 如果 H2 不在类路径里面,会出现上面情况?
将会报下面的错误
Cannot determine embedded database driver class for database type NONE
把 H2 添加至 pom.xml 中,然后重启你的服务器
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
问题三十二 你能否举一个以 ReadOnly 为事务管理的例子?
当你从数据库读取内容的时候,你想把事物中的用户描述或者是其它描述设置为只读模式,以便于 Hebernate 不需要再次检查实体的变化。这是非常高效的。
问题三十三 发布 Spring Boot 用户应用程序自定义配置的最好方法是什么?
@Value 的问题在于,您可以通过应用程序分配你配置值。更好的操作是采取集中的方法。
你可以使用 @ConfigurationProperties 定义一个配置组件。
@Component
@ConfigurationProperties("basic")
public class BasicConfiguration {
private boolean value;
private String message;
private int number;
你可以在 application.properties 中配置参数。
basic.value: true
basic.message: Dynamic Message
basic.number: 100
问题三十四 配置文件的需求是什么?
企业应用程序的开发是复杂的,你需要混合的环境:
Dev
QA
Stage
Production
在每个环境中,你想要不同的应用程序配置。
配置文件有助于在不同的环境中进行不同的应用程序配置。
Spring 和 Spring Boot 提供了你可以制定的功能。
不同配置文件中,不同环境的配置是什么?
为一个制定的环境设置活动的配置文件。
Spring Boot 将会根据特定环境中设置的活动配置文件来选择应用程序的配置。
问题三十五 如何使用配置文件通过 Spring Boot 配置特定环境的配置?
配置文件不是设别环境的关键。
在下面的例子中,我们将会用到两个配置文件
dev
prod
缺省的应用程序配置在 application.properties 中。让我们来看下面的例子:
application.properties
basic.value= true
basic.message= Dynamic Message
basic.number= 100
我们想要为 dev 文件自定义 application.properties 属性。我们需要创建一个名为 application-dev.properties 的文件,并且重写我们想要自定义的属性。
application-dev.properties
basic.message: Dynamic Message in DEV
一旦你特定配置了配置文件,你需要在环境中设定一个活动的配置文件。
有多种方法可以做到这一点:
在 VM 参数中使用 Dspring.profiles.active=prod
在 application.properties 中使用 spring.profiles.active=prod
9.5 微服务
微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
java微服务的框架有dubbo,spring cloud。dubbo服务务只是微服务基础设施的一个子集。
现在微服务主流的框架是spring boot,spring cloud和容器docker
1. SpringCloud和Dubbo有哪些区别?
最大区别:SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
总体来说,两者各有优势。虽说后者服务调用的功能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的依赖,这在强调快速演化的微服务环境下,显得更加合适。
品牌机与组装机的区别:很明显SpringCloud比dubbo的功能更强大,覆盖面更广,而且能够与SpringFramework、SpringBoot、SpringData、SpringBatch等其他Spring项目完美融合,这些对于微服务至关重要。使用Dubbo构建的微服务架构就像组装电脑、各环节我们选择自由度高,但是最总可能会因为内存质量而影响整体,但对于高手这也就不是问题。而SpringCloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性。
在面临微服务基础框架选型时Dubbo与SpringCloud只能二选一。
4、SpringBoot和SpringCloud,请你谈谈对他们的理解?
1)、SpringBoot专注于快速方便的开发单个个体微服务。
2)、SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。
3)、SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系。
5、什么是服务熔断?什么是服务降级?
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand
服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然水平下降,但好歹可用,比直接挂掉强。
6、微服务的优缺点是什么?说下你在项目开发中碰到的问题
优点:1)、每个服务足够内聚,足够小,代码容易理解这样能聚焦一个指定的业务功能或业务需求。
2)、开发简单,开发效率提高,一个服务可能就是专一的只干一件事。
3)、微服务能够被小团队开发,这个团队可以是2到5个开发人员组成。
4)、微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
5)、微服务能使用不同的语言开发。
6)、易于第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成集成工具,如Jenkins、Hudson等。
7)、微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作体现价值。
8)、微服务允许你融合最新技术。
9)、微服务知识业务逻辑代码,不会和HTML和CSS其他界面组件混合。
10)、每个微服务都有自己的存储能力,可以有自己的数据库,也可以由统一的数据库。
缺点:1)、开发人员要处理分布式系统的复杂性。
2)、多服务运维难度,随着服务的增加,运维的压力也在增加。
3)、系统部署依赖。
4)、服务间通讯成本。
5)、数据一致性。
6)、系统集成测试。
7)、性能监控.....
7、你所知道的微服务技术栈有哪些?请举例一二
微服务的技术栈(各项功能的实现所使用的技术)具体如下:
8、Eureka和zookeeper都可以提供服务注册与发现的功能,请说说两个的区别?
1)、Zookeeper保证了CP(C:一致性,P:分区容错性),Eureka保证了AP(A:高可用)
(1)、当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的信息,但不能容忍直接down掉不可用。也就是说,服务注册功能对高可用性要求比较高,但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选leader。问题在于,选取leader时间过长,30 ~ 120s,且选取期间zk集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够恢复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。
(2)、Eureka保证了可用性,Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点仍然可以提供注册和查询服务。而Eureka的客户端向某个Eureka注册或发现是发生连接失败,则会自动切换到其他节点,只要有一台Eureka还在,就能保证注册服务可用,只是查到的信息可能不是最新的。除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Eureka就认为客户端与注册中心发生了网络故障,此时会出现以下几种情况:
①、Eureka不在从注册列表中移除因为长时间没有收到心跳而应该过期的服务。
②、Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点仍然可用)
③、当网络稳定时,当前实例新的注册信息会被同步到其他节点。
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个微服务瘫痪