1、&和&&的区别。
&和&&都表示与的意思,既表达式俩边都成立,结果才成立。
&&是逻辑运算符,&&有短路作用,既当表达式左边为假时,不需要计算右边,整个的结果直接为假;&没有
&是位运算符,&的左右俩边可以是布尔类型,也可以是数值;&&俩边只能是布尔类型
2、==与equals的区别
从表面上看,对于基本数据类型==是判断的值是否相等;对于引用数据类型是判断是否为同一个对象,从本质上看,是看是否为一个引用地址;equals是判断值是否相等
3、override(重写)和overload(重载)的区别
重载是在一个类中,方法名相同,参数列表不同(参数类型和参数个数)的一种现象
1、重载与返回值类型无关
2、不能通过访问修饰符进行重载
重写是在父子类中,子类重写父类的方法,要求方法名与参数列表,返回值类型完全相同。子类重写父类规范要在子类的方法前加注解@Override
1、重写的返回值类型可以改,但只能是父子类
2、重写的访问修饰符得大于等于原来的
3、不能重写私有方法
4、参数列表的顺序与类型必须一样,变量名可不同
4、JDK,JRE,JVM的联系与区别?
JDK是java开发工具包,JDK包括JRE,类库,java工具
JRE是java运行环境,JRE包括JVM,JRE里有运行.class的java.exe
JVM是java虚拟机,java虚拟机在执行字节码时,把字节码解释成具体平台的机器指令执行,这也是java语言跨平台的根源,是“一次编译,到处运行”的原因
联系:JDK下的jre文件夹下有俩个文件夹lib和bin;在这里可以理解为bin就是jvm,lib就是类库;所以JRE=JVM+类库
利用JDK开发属于自己的java程序,javac编译成字节码,在JRE上运行这些字节码,JVM解析这些字节码,最终映射到CPU指令集或OS的系统调用
区别:
JDK与JRE的区别:
1.JDK有javac.exe;JRE没有
2.JDK是开发环境,JRE是运行环境
JRE与JVM的区别:
JVM执行.class需要JRE下lib类库的支持(尤其是rt.jar)
5、String s = new String("xyz");创建了几个String Object
创建了俩个对象或一个对象,如果常量池中没有“xyz”第一次=在常量池中创建了一个字符串对象,第二次new又创建了一个字符串引用对象;如果常量池中有“xyz”,那就只是new的时候创建了一个对象
6、Java中的String,StringBuilder,StringBuffer三者的区别?
1.String是不可变字符串,StringBuilder和StringBuffer是可变字符串
2.从运行效率看,StringBuilder>StringBuffer>String
3.StringBuilder非线程安全,StringBuffer线程安全
总结:String适合少量字符串的操作
StringBuilder适合单线程大量数据的操作
StringBuffer适合多线程大量数据的操作
7、构造器Constructor是否可被override?
构造器不能被重写,因为构造器不能被继承,但它可以重载
8、Vector和ArrayList的区别
ArrayList和Vector是基于数组的,有下标,有序,元素可重复。
Vector就是把ArrayList中的所有方法加了synchronized
所以,Vector是线程安全的,ArrayList是线程不安全的,但Collections下有静态方法,synchronizedList来代替Vector,Vector在日常中很少使用。
9、sleep() 和 wait() 有什么区别?
1)sleep是Thread类下的方法;wait是Object下的方法
2)sleep是使线程休眠,不释放锁;wait是使线程等待,释放锁
sleep让出的是cpu,如果此时代码是加锁的,那么即使让出了CPU,其他线程也无法运行,因为没有得到锁;wait是让自己暂时等待,让出同步锁,等待其他线程执行完了,再来执行自己
3)调用sleep进入阻塞状态;调用wait进入就绪状态
10、Java中的HashMap的工作原理是什么?
HashMap的原理是:数组+链表。
HashMap类有一个叫Entry的内部类。这个Entry类包含了key-value作为实例变量。根据key的hashcode方法计算出hash值来决定具体在哪个位置,如果这个位置有值,则调用equals方法进行判断,如果equals相等则替换,如果equals不等则追加到链表后。
11、什么是序列化,如何实现序列化?
序列化机制(包括序列化和反序列化)的本质是用流将对象读到内存和写入外存。
序列化机制的意义就是将对象脱离程序运行独立存在
应用场景是在RMI(远程方法调用)中应用,即通过网路或跨平台传输对象,而RMI是javaEE开发基础,所以javaEE要求传递的参数与返回值都实现序列化机制
序列化是用流将java对象转成二进制写入硬盘或网络
反序列化是用流将二进制数据转为java对象写入内存
实现序列化需要实现Serializable或Externalizable接口,如果某个成员变量是引用数据类型,那么要求该引用类也是可序列化的。如果类中每个成员变量不想被序列化,可以用transient关键字修饰。
序列化通常与IO中的ObjectInputStream(readObject方法)和ObjectOutputStream(writeObject方法)搭配使用
12、什么是单例模式?
单例模式是指一个类只创建一个实例。
单例模式是经常用到的一种设计模式,它分为饿汉式、懒汉式、静态内部类、枚举
饿汉式:在类加载时就创建本类对象为私有静态常量,构造方法写成私有的,使用共有静态方法代替构造方法获取到这个单例
懒汉式:在饿汉式的基础上给静态方法加synchronized,在方法里判断本类对象是否为空,为空时创建。
静态内部类:将单例放在静态内部类中,避免在类加载的时候就创建对象,然后用静态方法代替私有构造
13、对象的深拷贝与浅拷贝
对象的深拷贝是在拷贝时把这个对象复制一份,如果这个对象所属的类中有引用数据类型,也会将引用该类复制一份,以达到深度克隆,这样的话,一个改变了它的值不会影响另一个
实现深拷贝的方法:
覆盖Object的clone方法
通过序列化方式实现深拷贝
对象的浅克隆是在拷贝时把这个对象复制一份,但如果这个对象所属的类中有引用数据类型,这个引用还指向原来的引用。
例如:从A拷贝一份B,如果是深克隆,A和B是俩个独立的对象,只不过一模一样。如果是浅克隆,如果A中有引用类型,那么B中此引用类型和A中此引用类型指向的是同一块地址。
14、什么是反射
反射是在运行时动态的获取类的信息,获取Class对象有三种方法:类名.class、对象名.getClass()、Class.forName(“权限定名”)
获取到类对象后可以用newInstance()创建对象,Class类中API提供了获取属性、方法、构造器的方法
15、面向对象的特征
面向对象有三大特征:封装、继承、多态
封装是将重复利用的代码包装起来,以便其他处引用,提高了代码的可重用性
继承是发生在父子类之间的,子类继承父类开放权限的所有代码,其实继承破坏了封装性
多态是在不改变程序的代码的情况下,在程序运行时动态的绑定代码,使程序出现多种状态
多态的体现是继承、重写、父类引用指向子类对象
16、乐观锁与悲观锁的区别?
悲观锁是将锁给一个线程,其他线程等待这个线程释放锁
乐观锁是先进行业务处理,最后一步更新数据时再加锁
①悲观锁适合于写频繁;乐观锁适合于读取频繁
②悲观锁是先加锁后进行业务逻辑;乐观锁是先进行业务逻辑再加锁
用普通for循环,并且在循环中i—
用一个List 记录要删除的数据,最后在原集合中removeAll(List);
用迭代器自带的remove方法
18、Java是如何实现多线程的?
(1)继承Thread类,重写run方法,调用这个类的start方法
(2)实现Runnable接口
(3)实现Callable接口,重写call方法,搭配FutureTask类使用
1、Maven的生命周期?
Maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
Maven有三套相互独立的生命周期,分别是clean、default和site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
1、clean生命周期:清理项目,包含三个phase。
1)pre-clean:执行清理前需要完成的工作
2)clean:清理上一次构建生成的文件
3)post-clean:执行清理后需要完成的工作
2、default生命周期:构建项目,重要的phase如下。
1)validate:验证工程是否正确,所有需要的资源是否可用。 2)compile:编译项目的源代码。 3)test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。 4)Package:把已编译的代码打包成可发布的格式,比如jar。 5)integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。 6)verify:运行所有检查,验证包是否有效且达到质量标准。 7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。 8)Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
3、site生命周期:建立和发布项目站点,phase如下
1)pre-site:生成项目站点之前需要完成的工作
2)site:生成项目站点文档
3)post-site:生成项目站点之后需要完成的工作
4)site-deploy:将项目站点发布到服务器
2、Spring 事务实现方式?
编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务
3、Spring 事务底层原理?
划分处理单元——IoC
AOP拦截需要进行事务处理的类
对事务处理实现(事务的生成、提交、回滚、挂起)
4、什么是Spring IOC 容器?
Spring IOC负责创建对象、管理对象(通过依赖注入)、整合对象、配置对象以及管理这些对象的生命周期。
5、Spring面向切面编程(AOP)?
向切面编程(AOP):允许程序员模块化横向业务逻辑,或定义核心部分的功能,例如日志管理和事务管理。
切面(Aspect) :AOP的核心就是切面,它将多个类的通用行为封装为可重用的模块。该模块含有一组API提供 cross-cutting功能。例如,日志模块称为日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
通知(Advice):通知表示在方法执行前后需要执行的动作。实际上它是Spring AOP框架在程序执行过程中触发的一些代码。Spring切面可以执行一下五种类型的通知:
* before(前置通知):在一个方法之前执行的通知。
* after(最终通知):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
* after-returning(后置通知):在某连接点正常完成后执行的通知。
* after-throwing(异常通知):在方法抛出异常退出时执行的通知。
* around(环绕通知):在方法调用前后触发的通知。
切入点(Pointcut):切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
引入:引入允许我们在已有的类上添加新的方法或属性。
目标对象:被一个或者多个切面所通知的对象。它通常是一个代理对象。也被称做被通知(advised)对象。
代理:代理是将通知应用到目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。有以下几种代理:
* BeanNameAutoProxyCreator:bean名称自动代理创建器
* DefaultAdvisorAutoProxyCreator:默认通知者自动代理创建器
* Metadata autoproxying:元数据自动代理
织入:将切面和其他应用类型或对象连接起来创建一个通知对象的过程。织入可以在编译、加载或运行时完成。
6、BeanFactory和ApplicationContext有什么区别?
ApplicationContext提供了一种解决文档信息的方法,一种加载文件资源的方式(如图片),他们可以向监听他们的beans发送消息。另外,容器或者容器中beans的操作,这些必须以bean工厂的编程方式处理的操作可以在应用上下文中以声明的方式处理。应用上下文实现了MessageSource,该接口用于获取本地消息,实际的实现是可选的。
相同点:两者都是通过xml配置文件加载bean,ApplicationContext和BeanFacotry相比,提供了更多的扩展功能。
不同点:BeanFactory是延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。
7、Spring 的单例实现原理?
Spring框架对单例的支持是采用单例注册表的方式进行实现的,而这个注册表的缓存是HashMap对象,如果配置文件中的配置信息不要求使用单例,Spring会采用新建实例的方式返回对象实例。
8、Resource 是如何被查找、加载的?
Resource 接口是 Spring 资源访问策略的抽象,它本身并不提供任何资源访问实现,具体的资源访问由该接口的实现类完成——每个实现类代表一种资源访问策略。 Spring 为 Resource 接口提供了如下实现类:
* UrlResource:访问网络资源的实现类。
* ClassPathResource:访问类加载路径里资源的实现类。
* FileSystemResource:访问文件系统里资源的实现类。
* ServletContextResource:访问相对于 ServletContext 路径里的资源的实现类:
* InputStreamResource:访问输入流资源的实现类。
* ByteArrayResource:访问字节数组资源的实现类。 这些 Resource 实现类,针对不同的的底层资源,提供了相应的资源访问逻辑,并提供便捷的包装,以利于客户端程序的资源访问。
9、Spring中的依赖注入是什么?
依赖注入作为控制反转(IOC)的一个层面,可以有多种解释方式。在这个概念中,你不用创建对象而只需要描述如何创建它们。你不必通过代码直接的将组件和服务连接在一起,而是通过配置文件说明哪些组件需要什么服务。之后IOC容器负责衔接
9.1有哪些不同类型的IOC(依赖注入)?
构造器依赖注入:构造器依赖注入在容器触发构造器的时候完成,该构造器有一系列的参数,每个参数代表注入的对象。
Setter方法依赖注入:首先容器会触发一个无参构造函数或无参静态工厂方法实例化对象,之后容器调用bean中的setter方法完成Setter方法依赖注入。
10、Spring MVC 运行流程?
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler( 可以根据xml配置、注解进行查找)
第三步:处理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView(ModelAndView是springmvc框架的一个底层对象,包括Model和view)
第八步:前端控制器请求视图解析器去进行视图解析(根据逻辑视图名解析成真正的视图(jsp))
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染( 视图渲染将模型数据(在ModelAndView对象中)填充到request域)
第十一步:前端控制器向用户响应结果
11、解释Spring框架中bean的生命周期?
1.首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化
2.按照Bean定义信息配置信息,注入所有的属性
3.如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id
4.如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory
5.如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext,
6.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法
7.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法
8.如果Bean配置了init-method方法,则会执行init-method配置的方法,
9.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,
10.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了
11.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,
12.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束
12、Spring 事务回滚实现原理
在Service层的方法上加上@Transactional注解,在发生错误时,方法会抛出运行时异常,随即Spring会自动回滚事务。
使用 @Transaction 来配置自动回滚,可以配置在类上,也可以配置在方法上(作用域不同),但对final或private修饰的方法无效,且该类必须是受spring所管控的。若被配置的方法或类抛出了异常,则事务会被自动回滚,除非你在该方法中手动捕获了异常。可以使用 @Transactional(rollbackFor = Exception.class) 来设定针对特定的异常进行事务回滚,如果不设置则默认会回滚 RuntimeException and Error (参考自源码内文档)。
Spring实现事务回滚的流程如下:
1、通过cglib,将方法上加了@Transactional注解的类创建生成代理对象
2、Controller在调用Service方法时,由于Service是代理对象,便会进入到DynamicAdvisedInterceptor类的intercept方法中,
try catch包住要执行的事务方法,如果发生报错,就在catch中回滚事务
13、解释自动装配的各种模式?
自动装配提供五种不同的模式供Spring容器用来自动装配beans之间的依赖注入:
no:默认的方式是不进行自动装配,通过手工设置ref 属性来进行装配bean。
byName:通过参数名自动装配,Spring容器查找beans的属性,这些beans在XML配置文件中被设置为byName。之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
byType:通过参数的数据类型自动自动装配,Spring容器查找beans的属性,这些beans在XML配置文件中被设置为byType。之后容器试图匹配和装配和该bean的属性类型一样的bean。如果有多个bean符合条件,则抛出错误。
constructor:这个同byType类似,不过是应用于构造函数的参数。如果在BeanFactory中不是恰好有一个bean与构造函数参数相同类型,则抛出一个严重的错误。
autodetect:如果有默认的构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。
14、pring有几种配置方式?
将Spring配置到应用开发中有以下三种方式:1.基于XML的配置2.基于注解的配置3.基于Java的配置
15、Spring 框架中都用到了哪些设计模式?
工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean默认为单例模式。
代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
16、Spring框架中的单例bean是线程安全的吗?
不是,Spring框架中的单例bean不是线程安全的。
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。
17、Spring如何处理线程并发问题?
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
类型用于注入一列值,允许有相同的值。
19、@Component, @Controller, @Repository, @Service 有何区别?
@Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
@Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。
@Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。
@Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。
20、说一下 spring 的事务隔离?
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
ISOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
ISOLATION_READ_COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据。
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了
1、SpringBoot有哪些优点?
独立运行。内嵌了servlet,tomat等,不需要打成war包部署到容器中,只需要将SpringBoot项目打成jar包就能独立运行。
简化配置。启动器自动依赖其他组件,简少了 maven 的配置。各种常用组件及配置已经默认配置完成,无需过多干预。
避免大量的Maven导入和各种版本冲突
应用监控Spring Boot 提供一系列端点可以监控服务及应用。
2、Spring Boot 的核心配置文件有哪几个?它们的区别是什么?
Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
application 配置文件,主要用于 Spring Boot 项目的自动化配置。
bootstrap 配置文件有以下几个应用场景。
使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
一些固定的不能被覆盖的属性;
一些加密/解密的场景;
3、Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。代表当前是一个配置类
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。
4、SpringBoot自动配置原理是什么?
SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration。
查看@EnableAutoConfiguration,其作用是利用AutoConfigurationImportSelector给容器中导入一些组件。
查看AutoConfigurationImportSelector,其中public String[] selectImports(AnnotationMetadata annotationMetadata)方法内 最终调用getCandidateConfigurations()方法
查看 getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes),获取候选的配置,这个是扫描所有jar包类路径下"META-INF/spring.factories"
然后把扫描到的这些文件包装成Properties对象。
从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把他们添加在容器中。
简而言之,整个过程就是将类路径下"META-INF/spring.factories"里面配置的所有EnableAutoConfiguration的值加入到容器中。
5、开启SpringBoot 特性有哪几种方式?
继承spring-boot-starter-parent项目
导入spring-boot-dependencies项目依赖
6、如何理解 Spring Boot 中的 Starters?
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。
Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
7、Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
Spring Boot 支持 Java Util Logging, Log4j2, Lockback 作为日志框架,如果你使用 Starters 启动器,Spring Boot 将使用Logback 作为默认日志框架
8、SpringBoot中如何解决跨域问题 ?
1)、基于WebMvcConfigurerAdapter配置加入Cors的跨域
跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此我们推荐在后端通过(CORS,Cross-origin resource sharing)
来解决跨域问题。这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS ,现在可以通过实现WebMvcConfigurer接口然后重写
addCorsMappings方法解决跨域问题
2)、创建一个filter解决跨域
项目中前后端分离部署,所以需要解决跨域的问题。 我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。 当用户登录以后,正常使用;
当用户退出登录状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。 我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行。
3)、controller配置CORS
controller方法的CORS配置,可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法)
@CrossOrigin 表示所有的URL均可访问此资源
@CrossOrigin(origins = “http://127.0.0.1:8080”) 表示只允许这一个url可以跨域访问这个controller
@CrossOrigin这个注解用起来很方便,这个可以用在方法上,也可以用在类上。如果你不设置他的value属性,或者是origins属性,就默认是可以允许所有的URL/域访问。
-value属性可以设置多个URL。
-origins属性也可以设置多个URL。
-maxAge属性指定了准备响应前的缓存持续的最大时间。就是探测请求的有效期。
-allowCredentials属性表示用户是否可以发送、处理 cookie。默认为false
-allowedHeaders 属性表示允许的请求头部有哪些。
-methods 属性表示允许请求的方法,默认get,post,head。
9、如何实现SpringBoot 应用程序的安全性?
为了实现Spring Boot的安全性,使用 spring-boot-starter-security依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法
10、如何集成SpringBoot 和 ActiveMQ
对于集成Spring Boot和ActiveMQ,使用spring-boot-starter-activemq 依赖关系。它只需要很少的配置,并且不需要样板代码。
11、SpringBoot 中的监视器是什么呢?
Spring boot actuator是spring启动框架中的重要功能之一。
Spring boot监视器可帮助访问生产环境中正在运行的应用程序的当前状态。
例如创建了什么bean、控制器中的映射、CPU 使用情况等等。然后可以将自动收集和审计健康状况(health)以及指标(metric)到应用程序中。
12、如何使用SpringBoot实现异常处理?
Spring提供了一种使用ControllerAdvice处理异常的非常有用的方法。
通过实现一个ControlerAdvice类,来处理控制器类抛出的所有异常。
13、RequestMapping和GetMapping的不同之处在哪里?
RequestMapping 具有类属性的,可以进行 GET,POST,PUT 或者其它的注释中具有的请求方法。
GetMapping 是 GET 请求方法中的一个特例。
它只是 ResquestMapping 的一个延伸,目的是为了提高清晰度
14、SpringBoot打成的jar和普通jar有什么区别?
Spring Boot 项目最终打包成的 jar 是可执行 jar ,这种 jar 可以直接通过 java -jar xxx.jar 命令来运行,这种 jar 不可以作为普通的 jar 被其他项目依赖,即使依赖了也无法使用其中的类。
Spring Boot 的 jar 无法被其他项目依赖,主要还是他和普通 jar 的结构不同。
普通的 jar 包,解压后直接就是包名,包里就是我们的代码,而 Spring Boot 打包成的可执行 jar 解压后,在 \BOOT-INF\classes 目录下才是我们的代码,因此无法被直接引用。
如果非要引用,可以在 pom.xml 文件中增加配置,将 Spring Boot 项目打包成两个 jar ,一个可执行,一个可引用
15、SpringBoot中如何实现定时任务?
Spring Boot 中对于定时任务的支持主要还是来自 Spring 框架。
在 Spring Boot 中使用定时任务主要有两种不同的方式,
一个就是使用 Spring 中的 @Scheduled 注解,
另一个则是使用第三方框架 Quartz。
使用 Spring 中的 @Scheduled 的方式主要通过 @Scheduled 注解来实现。
使用 Quartz ,则按照 Quartz 的方式,定义 Job 和 Trigger 即可
16、运行Spring Boot的方式
(1)直接执行main方法运行
(2)用Maven / Gradle插件运行
(3)打成jar包,通过java -jar命令直接运行