框架相关

简述JWT?

答:
概述:JWT是基于Token验证方式的一种基本实现

  1. Header :描述 JWT 的元数据。定义了生成签名的算法以及 Token 的类型。

  2. Payload(负载):用来存放实际需要传递的数据

  3. Signature(签名):服务器通过Payload、Header和一个密钥(secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

在基于 Token 进行身份验证的的应用程序中,服务器通过Payload、Header和一个密钥(secret)创建令牌(Token)并将 Token 发送给客户端,客户端将 Token 保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization字段中:Authorization: Bearer Token。

spring如何实现依赖注入?

答:spring实现依赖注入有两种方式:构造函数注入和setter注入

依赖注入可以理解Spring如何帮我们把我们在配置文件写的依赖关系实现。IOC可以认为是在中间加了一个代理,我们叫他做什么,他就做什么,原来new的方式可以理解为,我自己去做,而IOC是我叫你去做。

Spring如何解决循环依赖?

答:循环依赖如下图,就是A依赖B的同时B也依赖了A,或者C依赖了自己,在实例化的时候可能会导致,开始实例化A的时候发现A里面有B,然后又去实例化B,然后B里面又有A,无限循环


循环依赖
@Component
public class A {
 // A中注入了B
 @Autowired
 private B b;
}
---
@Component
public class B {
 // B中注入了A
 @Autowired
 private A a;
}
---
// 自己依赖自己
@Component
public class C {
 // C中注入了C
 @Autowired
 private C c;
}
  • 解决方法:
    • 三级缓存:1、singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用 2、earlySingletonObjects: 存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 3、singletonFactories:存放 bean 工厂对象,用于解决循环依赖

    • Spring 解决循环依赖的过程:

      • 首先 A 完成初始化第一步并将自己提前曝光出来(通过 ObjectFactory 将自己提前曝光),在初始化的时候,发现自己依赖对象 B,此时就会去尝试 get(B),这个时候发现 B 还没有被创建出来
      • 然后 B 就走创建流程,在 B 初始化的时候,同样发现自己依赖A,于是尝试 get(A),这个时候由于 A 已经添加至缓存中(一般都是添加至三级缓存 singletonFactories ),通过 ObjectFactory 提前曝光,所以可以通过 ObjectFactory.getObject() 方法来拿到 A 对象,B拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中
      • 回到 A,A 也可以拿到 B 对象,完成初始化,到这里整个链路就已经完成了初始化过程了。

其实两重依赖就能解决循环依赖的问题了,比如A-B循环,A先初始化,然后发现A里面有B,那么就去初始化B,并把半成品的A放进二级缓存里,然后B里面发现有A,去缓存里找,找到,B成功初始化,放进一级缓存,然后A创建也就完成了。那么为什么还要三重缓存呢,这里主要是为那些有AOP的Bean对象考虑,我们假设A是有经过代理,我们可以在二重循环中发现在B从缓存获取A的时候,获取的是半成品的A,而这个A还没有经过代理,所以跟我们想象的是完全不同的,所以Spring定义了第三级缓存,在第三级缓存中判断返回半成品引用的时候,是否需要进行代理,这里会返回有代理没有代理的引用。

Spring中bean的作用域?

答:
在spring配置文件定义Bean时,通过声明scope配置项,可以定义Bean的作用域,一共有五种:

1、singleton:IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。(默认的作用域

2、prototype:IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例

3、request:该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。

4、 session:该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。

5、global-session:该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

Spring中bean的生命周期?

答:

1. 实例化Bean

  • 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
  • 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。
  • 容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入(还没有为成员变量赋值)。
  • 实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性。

2. 设置对象属性(依赖注入)

  • 实例化后的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。
  • 紧接着,Spring根据BeanDefinition中的信息进行依赖注入。
  • 并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

3. 注入Aware接口(让Bean对象知道Spring的存在,比如BeanNameAware,就是让Bean知道自己在Spring里的ID)

  • 紧接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。

4. BeanPostProcessor
当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。
该接口提供了两个函数:

  • postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行,因此称为前置处理。 所有Aware接口的注入就是在这一步完成的。
  • postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行,因此称为后置处理。

5. InitializingBean与init-method
当BeanPostProcessor的前置处理完成后就会进入本阶段。 InitializingBean接口只有一个函数:

  • afterPropertiesSet()
    这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。 若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。

  • 当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。

6. DisposableBean和destroy-method
和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。

Spring 事务中哪几种事务传播行为?

答:
事务传播行为是为了解决业务层方法之间互相调用的事务问题。

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。

正确的事务传播行为可能的值如下:

1.TransactionDefinition.PROPAGATION_REQUIRED

使用的最多的一个事务传播行为,我们平时经常使用的@Transactional注解默认使用就是这个事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

2.TransactionDefinition.PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。

3.TransactionDefinition.PROPAGATION_NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

4.TransactionDefinition.PROPAGATION_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

这个使用的很少。

Mybatis的映射配置文件中,动态传递参数有两种方式:#{}和${},它们有什么区别?

答:
1、#{}为参数占位符?即sql预编译,${}为字符串替换,即sql拼接

2、变量替换后,#{} 对应的变量自动加上单引号,${} 对应的变量不会加上单引号

3、#{}能防止sql注入,${}不能防止sql注入

简述Shiro?

答:首先我们的权限认证基本上基于下图。


认证过程

先验证你是否有这个用户,然后再获取该用户相关的权限(这里有两种划分形式,将某一个特定的权限分配给用户,还是将特定的权限集合在一起,成为一个角色,再分配给用户)
而shiro以三个主要的对象来实现这些功能,分别是subject、SecurityManager、Realm

  • subject:这个主要是跟我们的外层逻辑交互的对象,也就是说我们可以根据这个对象的一些方法来判断是否有权限,是否是某个角色,来进行资源管理
  • SecurityManager:他负责所有的subject的管理,比如认证和授权、还有缓存等相关管理
  • Realm:这个也就是我们大部分代码的集中区域了,这里主要有两个方法,认证方法和授权方法,subject的角色与权限都是再这里进行逻辑产生的。

Springboot自动装配原理?

答:

  • 什么是自动装配:通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能。
  • 原理:在我们每一个SpringBoot应用中,有一个注解@SpringBootApplication,大概可以把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。这三个注解的作用分别是:
    1、@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制。
    2、@Configuration:允许在上下文中注册额外的 bean 或导入其他配置类。
    3、@ComponentScan: 扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilter和AutoConfigurationExcludeFilter。
    而这里的enableAutoConfiguration是实现自动装配的关键,这里注解会导入一个类AutoConfigurationImportSelector,他实现了一个接口ImportSelector,接口定义了一个方法selectImports该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中。而在具体的这个方法的实现中,有个叫getAutoConfigurationEntry()的方法被调用。这个方法第一步会判断自动装配是否开启,第二步获取Exclude和Excludename。第三步获取需要自动装配的所有配置类,读取META-INF/spring.factories。这个文件里有我们需要自动装配的所有类的全类名。接着就利用反射将对应的类注入Spring容器即可。而且也并不是每次自动装配都是完完全全装配所有的类的。有一个注解@ConditionalOnXXX,他可以做一些逻辑判断,在某些时候一些是没有必要装配的。另外引入一个starter,他在meta-inf/spring.factories的配置就会被读取,然后自动装配相应的类
  • 如何实现一个 Starter:
  1. 首先我们要引入Spring的相关依赖,比如Spring给我们定义Starter的基本版本,我们在Maven中加dependence即可。
  2. 将相应的类加上@Bean和@ConditionalOnClass(如果不设置条件也可以不添加)
  3. 最后在mete-inf/的Spring.factory中写上自动装配类的全类名即可
  4. 这样一个Starter就完成了

总结:也就是说我们Spring的启动注解中,包含了一个enableAutoConfiguration的这个注解,这个注解会导入一个实现自动装配的类,他有一个方法,会扫描所有Starter的Spring.factory文件里的相关类,而且并不是每次都加载全部,在ConditionOnclass的注解下可能只会装配部分。

Spring IOC的理解?

答:中间人,门面模式,从你自己做,到你叫别人帮你做,其实本质上我认为就是,将那些通用或者难实现的代码,交给哪些最厉害的程序员去写,而我们只注重我们的个性化需求,但是你如果没有通过容器,直接new这样,无从下手,所以采用门面模式

将类交给spring容器的3种办法

答:

  • 注解方式:
    1@Bean
    2)@Component
    3)@Import方式
  • XML方式:
    4)xml注册Bean,如果spring配置元数据的方式是xml时,可以手动在xml注册第三方jar包中的类。

spring源码aop怎么实现的,aop用在哪里?

答:原理就是当我们从Spring容器中获取bean的时候,他根据动态代理返回一个代理对象,具体代理在调用我们真正的方法的时候用了什么,是基于我们自己的注解配置。动态代理参考其他

拦截器和过滤器的区别?

参考链接

@AutoWired、@Qualified、@Resource三个注解的区别 ?

答:
一、@Autowired,@Qualifier

// @Autowired只按照类型注入,如果想按照名称注入,配合@Qualifier使用
@Autowired
@Qualifier("studentDao")

二、@Resource

// 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
@Resource(name = "studentDao",type = StudentDao.class)

// 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
@Resource(name = "studentDao")

// 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
@Resource(type = StudentDao.class)

// 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
@Resource

本质上两者都是标志bean自动注入,只是标准不同,Resource是JDK中的标准,假如有其他DI框架也同样适用

事务传播机制底层原理?

事务传播机制基本概念
事务传播机制具体例子
事务底层实现原理

  • 什么是事务的传播
    Spring 除了封装了事务控制之外,还抽象出了 事务的传播 这个概念,事务的传播并不是关系型数据库所定义的,而是Spring在封装事务时做的增强扩展,可以通过@Transactional 指定事务的传播,具体类型如下

  • 为什么会有传播机制?
    spring 对事务的控制,是使用 aop 切面实现的,我们不用关心事务的开始,提交 ,回滚,只需要在方法上加 @Transactional 注解,这时候就有问题了。

  • 场景一: serviceA 方法调用了 serviceB 方法,但两个方法都有事务,这个时候如果 serviceB 方法异常,是让 serviceB 方法提交,还是两个一起回滚。

  • 场景二:serviceA 方法调用了 serviceB 方法,但是只有 serviceA 方法加了事务,是否把 serviceB 也加入 serviceA 的事务,如果 serviceB 异常,是否回滚 serviceA 。

  • 场景三:serviceA 方法调用了 serviceB 方法,两者都有事务,serviceB 已经正常执行完,但 serviceA 异常,是否需要回滚 serviceB 的数据。

  • 传播机制生效条件
    因为 spring 是使用 aop 来代理事务控制 ,是针对于接口或类的,所以在同一个 service 类中两个方法的调用,传播机制是不生效的

1、PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。Spring的默认事务传播类型

2、PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

3、PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。

4、PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起(暂停)。

5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容