Spring面试整理

1、SpringBoot可以同时处理多少请求
根据内置的tomcat配置文件判断,
max-connections最大连接数(默认8192)+ accept-count最大等待数(默认100)= 8292

server.tomcat.threads.max-connections = 8192(默认) //最大连接数
server.tomcat.threads.accept-count = 100(默认) //最大等待数
server.tomcat.threads.min-spare = 10 //最少线程数
server.tomcat.threads.max = 20 //最多线程数

2、SpringBoot如何优化启动速度
1)设置所有的bean为懒加载(默认是启动时加载,改为懒加载后变成用到时再加载)
spring.main.lazy-initialization = true
2)创建扫描索引 在启动类上加(@Indexed)
引入依赖

org.springframework
spring-context-indexer
true

3、聊聊spring是什么?
Spring是一个生态:可以构建java应用所需的一切基础设施
通常Spring指的就是Spring Framework
核心解释
spring是一个轻量级的开源容器架构
spring是为了解决企业级应用开发的业务逻辑层和其他各层对象和对象 之间的耦合问题
spring是一个IOC和AOP的容器框架
IOC:控制反转
AOP:面向切面编程
容器:包含并管理应用对象的生命周期

4、spring的优缺点是什么?
优点:
1)方便解耦,简化开发
集中管理对象,使对象和对象之间的耦合度降低,方便维护对象。
2)AOP编程的支持
在不修改代码的情况下可以对业务代码进行增强,减少重复代码,提高开发效率,方便维护。
3)声明事务的支持
提高开发效率,只需要用@Transactional注解
4)方便程序测试
Spring实现测试,使我们可以结合Junit非常方便测试 SpringBean SpringMVC
5)方便集成各种框架,集成能力强。
6)降低了JavaEE API的使用难度
简化开发,封装了非常多的功能性代码。

缺点:
1)从应用层面来说是没有缺点的
2)虽然简化了开发,但如果想深入到底层去了解就非常困难(上层使用越简单,底层封装的就越复杂)
3)源码缺点:代码量太大。

5、Spring IOC容器有什么作用?优点是什么?
IOC作用:
引入IOC,将创建对象的控制权交给了Spring的IOC,以前由程序员自己控制对象创建,现在交给Spring的IOC去创建,如果要去使用通过DI(依赖注入)@Autowired自动注入后,就可以使用对象了。
优点:集中管理对象,方便维护。降低耦合度。

6、Spring IOC的实现机制是什么?
工厂模式+反射

7、IOC和DI的区别是什么?
IOC控制反转是一种思想,将创建对象的权利交给了Spring。
DI(依赖注入)是IOC的实现,是实现IOC重要的一环。

8、紧耦合和松耦合有什么区别?
紧耦合:指的是类之间的高度依赖。
松耦合:通过促进单一职责和关注点分离、依赖倒置的设计原则来实现的。

9、BeanFactory的作用
1)BeanFactory是Spring中非常核心的一个顶层接口;
2)它是Bean工厂,它的主要职责就是生产Bean;
3)它实现了简单工厂的设计模式,通过调用getBean传入标识生产一个Bean;
4)它有非常多的现实类、每个工厂都有不同的职责(单一职责)功能,最强大的工厂是:DefaultListableBeanFactory Spring底层就是使用的该工厂进行生产Bean的.
5)BeanFactory也是容器, Spring容器(管理着Bean的生命周期)

10、说下Spring IOC容器的加载过程
1)实例化一个ApplicationContext的对象;
2)调用bean工厂后置处理器完成扫描;
3)循环解析扫描出来的类信息;
4)实例化一个BeanDefinition对象来存储解析出来的信息;
5)把实例化好的BeanDefinition对象put到BeanDefinitionMap当中缓存起来,以便后面实例化bean;
6)再次调用其他的bean工厂后置处理器;
7)当然spring还会干很多事情,比如国际化,比如注册BeanPostProcessor等等,如果我们只关心如何实例化一个bean的话那么这一步就是Spring要做验证,需要遍历所有扫描出来的类,依次判断这个bean是否Lazy,是否prototype,是否abstract等等;
8)如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法;
9)推断完构造方法之后spring调用构造方法反射实例化一个对象;这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入的,所以不是一个完整的bean;
10)spring处理合并后的beanDefinition;
11)判断是否需要完成属性注入;
12)如果需要完成属性注入,则开始注入属性;
13)判断bean的类型回调Aware接口;

11、什么是 bean
Spring Bean:
在Spring中,由Spring IOC容器管理的对象称为bean,bean是一个由Spring IOC容器实例化、组装和管理的对象.
Java Bean:
由编程者手动实例化.

12、配置bean有哪几种方式?
1)xml: 在配置文件中进行声明
2)通过注解:@Component(@Controller @Service @Repository) 前提:配置扫描包
3)javaConfig: @Bean (可以自己控制实例化过程)
4)@import (有三种方式)

13、Spring支持哪几种Bean的作用域
4种,singleton prototype request session

14、单例bean的优势(单例的设计模式优势是什么?)
由于不用每次都新创建新对象所以有以下几个性能上的优势:
1)减少了新生成实例的消耗.提高了服务器内存的利用率.减少了服务器内存的消耗.
2)减少jvm垃圾回收,由于不用给每个请求都新生成bean实例,自然就减少了对象的数量.
3)可以快速获取到bean,因为单例的获取bean操作,除了第一次生成之外其余的都是从缓存里获取的,所以很快.

15、Spring的bean是线程安全的么?
单例Bean的情况:
如果在类中声明成员变量,并且有读写操作[有状态],就不是线程安全的.
但是,把成员变量声明在方法中[无状态],单例Bean就是线程安全的.

16、Spring如何处理线程并发问题?
解决办法:
1)设置为多例(prototype),这样每次调用都会新生成bean对象.
2)将成员变量放在ThreadLocal中.
3)使用同步锁 synchronized .

17、Spring实例化bean有几种方式?
1)构造器方式(反射)
2)静态工厂方式,在配置文件<bean中>通过factory-method指定静态方法来创建实例化对象.
3)实例工厂方式(@Bean) factory-bean + factory-method
4)FactoryBean方式,通过实现[implement FactoryBean]FactoryBean中的方法来实例化对象.

18、什么是bean装配?什么是bean的自动装配?[参考: https://www.cnblogs.com/bear7/p/12531016.html ]
什么是装配:让bean与bean之间相互依赖起来
什么是手动装配:手动装配就是手动的将bean中所关联的其他bean装配进去.
什么是自动装配:自动装配就是Spring会在上下文中自动查找,并自动给bean装配与其关联的属性.
spring实现自动装配的方式有两种,一种是通过xml文件,一种是通过注解.

19、自动注入有什么需要注意的地方?(了解即可)
1)一定要声明set方法.
2)重写:你仍可以用和配置来定义依赖,这些配置将始终覆盖自动注入.
3)基本数据类型:不能自动装配简单的属性,如基本数据类型 字符串和类.(手动注入可以注入基本数据类型,,@Value)
4)模糊特性:自动装配不如显式装配精确,如果有可能尽量使用显式装配.
所以更推荐使用手动装配(@Autowired ref=“”)这种方式更加灵活更加清晰.

20、spring自动装配有哪些方式>解释一下不同的装配方式.
1)no:默认的方式是不进行自动装配的,通过手动设置ref属性来进行装配bean.
2)byName:通过bean的名称进行装配,如果一个bean的property与另一个bean的名称相同,则进行自动装配.
3)byType:通过参数的数据类型进行自动装配.(Class的类名称要求唯一)
4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配.

21、Bean有哪些生命周期回调方法?有哪几种实现方式?
分两类,一类是bean初始化的时候调用,一类是bean销毁时调用.
一bean初始化
1)@PostConstruct – 被注解标注的方法
2)InitializingBean – afterPropertiesSet
3)init-method – 通过配置指定的方法

二bean销毁
1)@PreDestory – 被注解标注的方法
2)DisposableBean – destory
3)destory-method – 通过配置指定的方法

22、Spring在加载过程中Bean有哪几种形态
1)概念态:@Bean Bean的配置形态
2)定义态:BeanDefinition 封装Bean的生产指标
3)纯净态:二级缓存 早期暴露Bean 循环依赖才体现纯静态的作用
4)成熟态:singleObject 最终在应用中使用的 bean

23、Spring框架中bean的生命周期
Bean生命周期:指的是Bean从创建到销毁的整个过程,分4大步:
1)实例化
a)通过反射去推断构造函数进行实例化
b)实例工厂 静态工厂
2)属性赋值
a)解析自动装配(byname bytype constractor none @Autowired) DI的体现
b)循环依赖
3)初始化
a)调用XXXAware回调方法
b)调用初始化生命周期回调(三种)
c)如果bean实现aop 创建动态代理
4)销毁
a)在string容器关闭的时候进行调用
b)调用销毁生命周期

24、Spring是如何解决Bean的循环依赖的?
Spring是如何解决循环依赖的:采用三级缓存解决的,就是三个Map
一级缓存:存储完整的Bean
二级缓存:避免多重循环依赖的情况 重复创建动态代理.
三级缓存:
1)缓存是函数接口:通过 lambda 把方法传进去(把Bean的实例和Bean的名字传进去了)[aop创建]
2)不会立即调用
3)会在 ABA (第二次getBean(A)才会取调用三级缓存(如果实现了aop才会创建动态代理,如果没有实现那么依然返回Bean的实例))
4)放入二级缓存(避免重复创建)

25、Spring是如何帮我们在并发下,避免获取不完整的Bean?
双重检查锁 2个同步锁 2次检查一级缓存

26、

27、

28、

29、Spring容器启动时,为什么先加载BeanFactoryPostProcess
1)因为BeanDefinition会在IOC容器加载的先注册,而BeanFactoryPostProcess就是在所有的BeanDefinition注册完后做扩展的,所以要先加载BeanFactoryPostProcess.
2)

30、Bean的创建顺序由什么决定的?
Bean的创建顺序是由BeanDefinition的注册顺序来决定的,当然依赖关系也会影响Bean创建顺序.

BeanDefinition的注册顺序由什么来决定的?
主要是由注解(配置)的解析顺序来决定的:
1)@Configuration
2)@Component
3)Import-类
4)@Bean
5)@Import-ImportBeanDefinitionRegistrar
6)BeanDefinitionRegistryPostProcessor

31、Spring有哪几种配置方式?
这里有三种重要的方法给Spring容器提供配置元数据:
1)XML配置文件
spring.xml
2)基于注解配置 Spring2.5+
spring.xml @Component @Autowired
3)基于java配置 JavaConfig Spring3.0+
@Configuration @Bean …

32、JavaConfig是如何替代spring.xml的?
应用:
1)以前Xml
a)Spring容器:ClassPathXmlApplicationContext(“xml”)
b)Spring.xml
c)
d)扫描包:
e)引入外部属性配置文件:
f)指定其他配置文件:
2)JavaConfig
a)spring容器:AnnotationConfigApplicationContext(JavaConfig.class)
b)配置类 @Configuration
c)@Bean @Scope @Lazy
d)扫描包:@ComponentScan
e)@PropertySource(classpath:db.properties)
f)@Import使用比较灵活

源码:

33、@Conponent,@Controller,@Repository,@Service 有何区别?
元注解 @Conponent = @Controller,@Repository,@Service
主要是增加代码的阅读性.
@Controller:标注在控制器上面
@Respository:标注在数据访问层上面
@Service:标注在业务逻辑层上面

34、@Import有几种用法?
1)直接导入类
2)导入配置类
3)导入ImportSelector的实现类
4)导入ImportBeanDefinitionRegister的实现类

35、如何让自动自动注入没有找到依赖Bean时不报错
@Autowired(required = false)
private User user;

36、如何让自动注入找到多个依赖Bean时不报错.
当有多个相同的bean时
1)使用@Primary来赋予bean更高的优先级.
2)@Qualifier(“beanName”).

37、Autowired注解有什么用?
Autowired是用来自动装配对象的.
可以使用在5种目标类型上:
a)构造器
b)方法
c)参数
d)成员变量
e)注解

38、@Autowired和@Resource之间的区别
1)Autowired是spring提供的,Resource是JDK提供的
2)Autowired默认根据类型匹配,当有多个时,再根据名字进行匹配.
Resource默认是根据名字进行匹配的,当名字匹配不到时,再根据类型进行匹配.

39、@Autowired自动装配的过程是怎么样的?
记住:@Autowired通过Bean的后置处理器来解析的
1)在创建一个spring上下文的时候在构造函数中进行注册 AutowiredAnnotationBeanPostProcessor
2)在Bean的创建过程中进行解析
a)在实例化后预解析(解析Autowired标注的属性/方法/ 比如:把属性的类型/名称属性所在的类…元数据缓存起来)
b)在属性注入真正的解析(拿到上一步缓存的元数据去IOC容器进行查找,并且返回注入)
*如果查询结果刚好是一个,就将该bean装配给@Autowired指定的数据;
*如果查询的结果是多个,那么@Autowired就会根据名称来查找;
*如果以上两步都没查找到,那么就会抛出异常.解决办法是,使用required=false

40、@Configuration的作用及解析原理

41、@Bean之间的方法调用是怎么保证单例的?、@Configuration加与不加的区别是什么?
1)如果希望@Bean的方法返回对象是单例,需要在类上面加@Configuration;
2)Spring会在invokeBeanFactoryPostProcessor通过内置BeanFactoryPostProcessor中会CGlib生成动态代理
3)当@Bean方法进行互调时,则会通过CGlib进行增强,通过调用的方法名作为bean的名称去IOC容器中获取,进而保证了@Bean方法的单例
总结怎么保证单例的:
因为spring底层会为@Configuration创建CGlib动态代理类,从而保证我们在调用内部方法的时候,就会增强到IOC容器中进行查找,以此来保证@Bean方法的单例.

42、要将一个第三方的类配成为Bean有哪些方式?
1)通过@Bean的方式来配置第三方
2)通过@Import直接导入类(但是这种方式无法干预实例化过程)
3)实现 ImportBeanDefinitionRegistrar 接口
4)实现 BeanDefinitionRegistryPostProcessor 接口(最后执行)

43、为什么@ComponentScan不设置basePackage也会扫描?
因为spring在解析@ComponentScan时会拿到basePackage.如果没有设置,会将当前类所在包的地址作为扫描包的地址.

44、什么是AOP,能做什么?
AOP,一般称为面向切面编程,用于那些与业务无关,但对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为切面,减少系统中重复代码,降低了模块的耦合度,同时提高了系统的可维护性.
常用于权限认证/日志/事务处理等.

AOP与OOP是面向不同领域的两种设计思想.
OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分.
AOP作为面向对象的一种补充,则是针对业务处理中的前面进行提取,已达到业务代码和公共行为代码之间低耦合性的隔离效果.
这两种设计思想在目标上由着本质的差异.

45、解释一下Spring AOP中 常见的概念名词
1)切面(Aspect):[在什么地方,要做什么,具体怎么做]
在AOP中切面指的就是"切面类".切面类中管理着增强的公共行为代码(通知)和切入方式(切点).
2)连接点(Join point):[在什么地方做]
指的是被增强的业务方法.
[在Spring AOP中,一个连接点总是代表一个方法的执行,其实就是增强的方法.]
3)通知(Advice):[具体怎么做]
就是需要增加到业务中的公共代码,通知有很多种类型分别可以在需要增加的业务方法不同的位置进行执行(前置通知/后置通知/异常通知/返回通知/环绕通知).
4)切点(PointCut):[很多连接点的集合]
决定哪些方法需要增强/哪些不需要增强,结合切点表达式进行实现.
5)目标对象(Target Object):[被代理对象]
目标对象指将要被增强的对象.即包含主业务逻辑的类的对象.
6)织入(Weaving):[织入是一个过程]
为目标对象创建动态代理的过程就叫织入.
把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象的过程.

46、Spring通知有哪些类型?
在AOP术语中,在的某个特定的连接点上执行的动作.
Spring切面可以应用5种类型的通知:
1)前置通知(Before):
在目标方法被调用之前执行的通知;
2)后置通知(After):
在目标方法完成之后执行的通知,此时不会关心方法的输出是什么;
3)返回通知(After-returning):
在目标方法返回值后执行的通知;
4)异常通知(After-throwing):
在目标方法抛出异常后执行的通知;
5)环绕通知(Around):
包含了上述4种通知类型,可以自定义通知的行为.

执行顺序:
正常:前置–>方法–>后置–>返回
异常:前置–>方法–>后置–>异常

Spring在5.2.7之后改变了advice的执行顺序.
正常:前置–>方法–>返回–>后置
异常:前置–>方法–>异常–>后置

47、JDK动态代理和CGLib动态代理的区别
四个主要区别:
1)JDK动态代理一定要实现接口,而CGLIB动态代理可以不实现接口.
2)JDK动态代理是通过自己内部生成字节码的方式生成代理类,而CGLIB动态代理通过ASM在运行时动态生成代理类和其他相关类.
3)JDK代理类是实现了目标接口,二CGLIB会将目标类作为父类进行继承.
4)JDK动态代理是通过反射的方式调用目标方法,而CGLIB是通过子类调用的父类方法的方式来调用目标方法的.

Spring AOP 中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
* JDK动态代理只提供接口的代理,不支持类的代理.
a)JDK会在运行时为目标类生成一个动态代理类 $proxy*.class
b)该代理类是实现了目标类接口,并且代理类会实现接口所有的方法增强代码.
c)调用时通过代理类先去调用处理类进行增强,再通过反射的方式进行调用目标方法.从而实现AOP.
* 如果代理类没有实现接口,那么 Spring AOP会选择使用CGLIB来动态代理目标类.
a)CGLIB的底层是通过ASM在运行时动态的生成目标类的一个子类.(还有其他相关类,主要是为增强调用时效率)会生成多个,
b)并且会重写父类所有的方法增强代码
c)调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用目标方法.从而实现AOP.
1)CGLIB是通过继承的方式做动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的.
2)CGLIB除了生成目标子类代理类,还有一个FastClass(路由类),可以(但不是必须)让本类方法调用进行增强,而不会像JDK代理那样本类方法调用增强会失效.
* 很多人会对比JDK和CGLIB的性能,JDK动态代理生成类速度快调用慢,CGLIB生成类速度慢但调用快,在老版本CGLIB的速度是JDK速度的10倍左右,但是实际上JDK的速度在版本升级的时候每次都提高很多性能,而CGLIB仍止步不前.
在对JDK动态代理与CGLIB动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGLIB要好20%左右.

48、AOP有几种实现方式
1)基于接口配置;
2)使用xml配置文件的方式来配置,使用命名空间;
3)使用注解@AspectJ的方式配置;
4)AcpectJ方式,这种方式与Spring没有关系,采用AspectJ进行动态织入的方式实现AOP,需要用AspectJ单独编译.

49、事务的4大特性
1)原子性 (Atomicity)
原子性指的是事务包含的所有操作要么全都成功,要么全都失败.
因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响.
2)一致性 (Consistency)
一致性指的是事务必须使数据库从一个一致性状态换到另一个一致性状态,
也就是说一个事务执行之前和执行之后都必须处于一致性状态.
3)隔离性 (Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务操作干扰,多个并发事务之间要相互隔离.
4)持久性 (Durability)
持久性指的是一个事务一旦被提交了,那么对数据库中的数据的改变就是永久的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作.

50、Spring支持的事务管理类型、Spring事务实现方式有哪些?
Spring支持两种类型的事务管理:
编程式事务管理:通过编程的方式管理事务,灵活性大维护难.
声明式事务管理:通过将业务代码和事务管理分离,只需要用注解和XML配置来管理事务.
实现声明式事务的3种方式:
1)基于接口配置 2)基于配置文件 3)基于注解@Transactional

51、说一下Spring的事务传播行为.
事务的传播性指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行?

传播行为类型:REQUIRED(默认)
外部不存在事务:开启新的事务
外部存在事务:融合到外部事务中
使用方式:@Transactional(propagation=Propagation.REQUIRED)
适用于增删改

传播行为类型:SUPPORTS
外部不存在事务:不开启新的事务
外部存在事务:融合到外部事务中
使用方式:@Transactional(propagation=Propagation.SUPPORTS)
适用于查询

传播行为类型:REQUIRES_NEW(默认)
外部不存在事务:开启新的事务
外部存在事务:不用外部事务,创建新的事务
使用方式:@Transactional(propagation=Propagation.REQUIRES_NEW)
适用于内部事务和外部事务不存在业务关联的情况,如日志

52、说一下Spring的事务隔离
脏读
1)一个事务读取了另一个事务中没有提交的数据,会在本事务中产生数据不一致的问题
解决方式:@Transactional(isolation=Isolation.READ_COMMITTED)
读已提交:READ_COMMITTED
要求Transaction1只能读取Transaction2已提交的数据。

不可重复读
2)一个事务中多次读取相同的数据,但是读取的结果不一样,会在本事务中产生数据不一致的问题。
解决方式:@Transactional(isolation=Isolation.REPEATABLE_READ)
可重复读:REPEATABLE_READ
确保Transaction1可以多次从一个字段中读取到相同的值,即Transaction1执行期间禁止其他事务对这个字段进行更新(行锁)。

幻影读
3)一个事务中,多次对数据进行整表数据读取(统计),但是结果不一样,会在本事务产生数据不一致的问题。
解决方式:@Transactional(isolation=Isolation.SERIALIZABLE)
串行化:SERIALIZABLE
确保Transaction1可以多次从一个表中读取到相同的行,在Transaction1执行期间,禁止其他事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。(表锁)

不同数据库有不同的事务隔离级别:
MYSQL:REPEATABLE_READ(可重复读)
ORACLE:READ_COMMITTED(读已提交)

53、Spring事务实现原理
1)解析切面 --> bean的创建前,第一个bean的后置处理器进行解析advisor(pointcut(通过@Transactional解析的切点),advise)(这个advisor是通过@EnableTransactionManagement注册了一个配置类,该配置类就配置了advisor))
2)创建动态代理 --> bean的初始化后调用bean的后置处理器进行创建动态代理(有接口使用jdk,没接口使用CGLIB),创建动态代理之前会先根据advisor中pointCut匹配@Transactional(方法里面是不是有/类上面是不是有/接口或父类上面是不是有),匹配到就创建动态代理
3)调用:动态代理
try{
4)创建一个数据库连接Connection,并且修改数据库连接的autocommit属性为false,禁止此连接的自动提交(这是实现spring事务非常重要的一步)
5)然后执行目标方法,方法中会执行数据库操作sql
}catch{
6)如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务.
}
7)执行完当前方法后,如果没有出现异常就直接提交事务.

54、Spring事务传播行为实现原理:
Spring的事务信息是存在ThreadLocal中的,所以一个线程永远只能有一个事务,
*融入:当传播行为是融入外部事务则拿到ThreadLocal中的Connection、共享一个数据库连接共同提交、回滚
*创建新事务:当传播行为是创建新事务,会将嵌套新事务存入ThreadLocal、再将外部事务暂存起来;当嵌套事务提交、回滚后,会将暂存的事务信息恢复到ThreadLocal中.

55、Spring多线程事务,能否保证事务的一致性(同时提交、同时回滚)?
1)Spring的事务信息是存在ThreadLocal中的,所以一个线程永远只能有一个事务
2)所以Spring的事务是无法实现事务一致性的
3)可以通过编程式事务,或者通过分布式事务的思路:二阶段提交方式。

56、Spring事务的失效原因
内部调用导致事务传播失败:
解决方式:必须走代理,重新拿到代理对象再次执行方法才能进行增强。
1)在本类中注入当前的Bean。
2)设置暴露当前代理对象到本地线程,可以通过AopContext.currentProxy()拿到当前正在调用的动态代理对象。

57、Spring是如何整合MyBatis管理Mapper接口的?
1)首先MyBatis的Mapper接口核心是JDK动态代理
2)Spring会排除接口,无法注册到IOC容器中
3)MyBatis实现了BeanDefinitionRegistryPostProcessor可以动态注册BeanDefinition
4)需要自定义扫描器(继承Spring内部扫描器ClassPathDefinitionScanner)重写排除接口的方法
5)但是接口虽然注册成了BeanDefinition但是无法实例化Bean,因为接口无法实例化
6)需要将BeanDefinition的BeanClass替换成JDK动态代理的实例
7)Mybatis通过FactoryBean的工厂方法设计模式可以自由控制Bean的实例化过程,可以在getObject方法中创建JDK动态代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉辰56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值