Spring源码笔记
spring的核心几个类是什么?
Spring的核心几个类包括:
-
ApplicationContext:应用程序上下文,是Spring框架的核心类,负责管理Bean的创建、依赖注入和生命周期等。
-
BeanFactory:Bean工厂,负责管理Bean的创建和依赖注入等。
-
BeanPostProcessor:Bean后置处理器,负责在Bean实例化、依赖注入和初始化完成后执行一些额外的操作,如添加拦截器、动态代理等。
-
BeanDefinition:Bean定义,描述了Bean的类型、属性和依赖关系等元数据。
-
BeanWrapper:Bean包装器,包装了一个Bean实例,提供了对Bean属性的访问和修改等功能。
-
AOP Alliance:Spring AOP的核心接口,定义了切面、切点、通知等概念,是实现Spring AOP的基础。
-
JdbcTemplate:Spring JDBC的核心类,封装了JDBC的操作,提供了更方便、更安全的数据库访问方式。
BeanFactory做了什么?
BeanFactory是Spring框架的核心接口之一,其主要作用是负责管理Bean的创建和依赖注入等。具体来说,BeanFactory会将应用程序中定义的Bean按照其定义的配置信息进行实例化,并管理它们的生命周期。
BeanFactory的主要功能包括:
-
解析Bean的配置信息:BeanFactory会解析应用程序中定义的Bean的配置信息,包括Bean的类型、属性和依赖关系等。
-
实例化Bean:根据Bean的配置信息,BeanFactory会创建Bean的实例,并进行实例化操作。
-
管理Bean的生命周期:BeanFactory会管理Bean的生命周期,包括Bean的初始化和销毁等操作。
-
注入Bean之间的依赖关系:BeanFactory会根据Bean之间的依赖关系,进行依赖注入,即将一个Bean所依赖的其他Bean注入到它的属性中。
-
提供访问Bean的方法:BeanFactory提供了一系列方法,用于访问和管理应用程序中的Bean,包括根据Bean的名称获取Bean实例、判断是否存在指定的Bean等。
BeanFactory是Spring框架中的一个重要组件,它是实现依赖注入和控制反转的基础,为应用程序提供了更加灵活和可扩展的Bean管理方式。
spring中Bean的生命周期是怎样的?
Spring中Bean的生命周期包括以下几个阶段:
-
实例化:当Spring容器启动时,根据配置文件或注解等方式,创建Bean的实例。
-
设置属性值:在实例化Bean后,Spring容器会根据配置文件或注解等方式,将Bean的属性值设置到相应的属性中。
-
Aware接口回调:如果Bean实现了Spring的Aware接口,Spring容器会在设置属性值后,调用相应的Aware接口方法,让Bean获取Spring容器的相关信息。
-
BeanPostProcessor前置处理器:如果存在BeanPostProcessor前置处理器,Spring容器会在Bean实例化后,调用BeanPostProcessor的方法对Bean进行前置处理。
-
初始化方法:如果Bean定义了初始化方法(如使用@PostConstruct注解),Spring容器会在Bean实例化和属性设置完成后,调用Bean的初始化方法。
-
BeanPostProcessor后置处理器:如果存在BeanPostProcessor后置处理器,Spring容器会在Bean的初始化方法调用之后,调用BeanPostProcessor的方法对Bean进行后置处理。
-
使用Bean:在Bean初始化完成后,可以通过Spring容器获取Bean实例,并使用它的服务。
-
销毁方法:如果Bean定义了销毁方法(如使用@PreDestroy注解),当Spring容器关闭时,会调用Bean的销毁方法进行资源的清理和释放。
Spring容器负责Bean的生命周期管理,包括Bean的创建、属性设置、初始化、后置处理和销毁等操作。这种方式可以让应用程序更加灵活和可扩展,同时也使得Bean的创建和管理变得更加方便和自动化。
spring的后置处理器有什么作用?
Spring的后置处理器是一种特殊的bean,它可以在bean的初始化和销毁阶段进行一些特定的操作。后置处理器可以对bean进行修改、增强或者验证等操作,从而实现对bean的定制化功能。
具体来说,后置处理器主要有以下作用:
-
扩展Bean的功能:后置处理器可以为bean添加新的属性、方法或者修改bean的属性值,从而扩展bean的功能。
-
实现Bean的AOP:后置处理器可以在bean创建过程中为bean动态地添加切面逻辑,实现AOP功能。
-
Bean属性验证:后置处理器可以在bean创建之后对bean的属性进行验证,确保bean的属性值符合规范。
-
Bean销毁前的清理工作:后置处理器可以在bean销毁前做一些清理工作,例如关闭资源等。
后置处理器为开发者提供了一种定制化的方式,可以对bean进行增强或者修改,从而满足不同的业务需求。
spring有多少次后置处理器?分别干了什么?
Spring有大约22个后置处理器。
- ApplicationContextAwareProcessor:实现了ApplicationContextAware接口,用于处理实现该接口的Bean的自动注入。
- BeanValidationPostProcessor:实现JSR-303 Bean Validation标准,用于对Bean进行数据验证。
- CustomAutowireConfigurer:用于处理自定义的Autowired注解。
- CommonAnnotationBeanPostProcessor:实现了CommonAnnotationBean接口,用于处理JSR-250注解。
- InitDestroyAnnotationBeanPostProcessor:实现了@PostConstruct和@PreDestroy注解,用于处理Bean的初始化和销毁操作。
- PersistenceAnnotationBeanPostProcessor:实现了JPA和Hibernate注解,用于处理持久化相关的注解。
- RequiredAnnotationBeanPostProcessor:实现了@Required注解,用于处理Bean的必要属性。
- AutowiredAnnotationBeanPostProcessor:实现了@Autowired和@Value注解,用于自动注入Bean。
- CommonAnnotationBeanPostProcessor:实现了CommonAnnotationBean接口,用于处理JSR-250注解。
- CustomScopeConfigurer:用于处理自定义的Scope注解。
- PropertyPlaceholderConfigurer:用于处理属性占位符,如${jdbc.url}。
- ScheduledAnnotationBeanPostProcessor:实现了@Scheduled注解,用于处理定时任务。
- ServletContextAwareProcessor:实现了ServletContextAware接口,用于处理实现该接口的Bean的自动注入。
- ServletContextParameterFactoryBean:用于获取ServletContext中的参数值。
- ServletRequestAwareProcessor:实现了ServletRequestAware接口,用于处理实现该接口的Bean的自动注入。
- ServletRequestParameterFactoryBean:用于获取ServletRequest中的参数值。
- ServletResponseAwareProcessor:实现了ServletResponseAware接口,用于处理实现该接口的Bean的自动注入。
- ServletResponseParameterFactoryBean:用于获取ServletResponse中的参数值。
- MessageSourceResourceBundleFactoryBean:用于从MessageSource中获取资源信息。
- EventListenerMethodProcessor:实现了@EventListener注解,用于处理事件监听。
- AsyncAnnotationBeanPostProcessor:实现了@Async注解,用于处理异步方法调用。
- LoadTimeWeaverAwareProcessor:实现了LoadTimeWeaverAware接口,用于处理实现该接口的Bean的自动注入。
spring怎么解决循环依赖问题?
Spring解决循环依赖问题的方式有两种:
- 构造函数注入
在构造函数注入中,Spring会先创建依赖对象的实例,再将其注入到另一个对象中。这样就可以避免循环依赖的问题。
例如,有两个类A和B,它们相互依赖,可以按照以下方式注入:
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
public class B {
private A a;
public B(A a) {
this.a = a;
}
}
- Setter方法注入
在Setter方法注入中,先创建对象A和B,然后将A注入到B中,再将B注入到A中。这样就可以解决循环依赖的问题。
例如,有两个类A和B,它们相互依赖,可以按照以下方式注入:
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
}
public class B {
private A a;
public void setA(A a) {
this.a = a;
}
}
在实际开发中,尽量避免循环依赖的出现,如果不可避免,可以采用上述两种方式解决循环依赖问题。
spring解决循环依赖的原理是什么?
Spring通过使用三级缓存解决循环依赖的问题。
----当两个或多个Bean彼此依赖时,Spring容器会先创建Bean的实例,但是并不会将它们注入到彼此中,而是通过依赖注入的方式在Bean创建后来解决循环依赖问题。
----三级缓存的实现原理是:在Bean创建的过程中,Spring容器在创建Bean的实例时,会先将它们放到一个专门的缓存中,这个缓存叫做“早期Bean缓存”,然后Spring会解析Bean之间的依赖关系,如果发现有循环依赖的情况,它会将当前Bean放到一个叫做“已经解决循环依赖的Bean缓存”中,然后继续创建其他Bean。最后,当所有的Bean都创建完毕之后,Spring会从“已经解决循环依赖的Bean缓存”中取出Bean,并将它们注入到其他Bean中。这样就可以解决循环依赖的问题。
spring在第几次后置处理器时处理循环依赖问题的?
Spring在第七个后置处理器"ApplicationContextAwareProcessor"中处理循环依赖问题。这个处理器会在所有bean实例化之后,在bean的属性注入之前,处理所有实现了ApplicationContextAware接口的bean,将ApplicationContext注入到这些bean中。在这个处理器中,Spring会检查是否存在循环依赖,如果存在,就会把当前bean放入一个专门用于解决循环依赖的缓存中,等到后面处理完所有bean之后再去解决循环依赖问题。
spring中ApplicationContext的作用是什么?
ApplicationContext是Spring框架中的一个重要组件,它是一个容器,用于管理应用程序中的所有bean。它的作用包括:
-
实现依赖注入:ApplicationContext负责创建、初始化和管理bean对象,同时也负责将这些对象注入到其他对象中,实现依赖注入。
-
实现AOP:ApplicationContext支持AOP(面向切面编程),可以通过配置来实现AOP,例如在方法执行前后添加日志、事务等。
-
提供事件机制:ApplicationContext提供了事件机制,可以在bean的生命周期中发布事件,其他bean可以监听这些事件并作出相应的处理。
-
管理资源:ApplicationContext可以管理各种资源,例如数据库连接、文件等,使得应用程序可以更加灵活地使用这些资源。
-
提供国际化支持:ApplicationContext支持国际化,可以通过配置来实现不同语言环境下的资源切换,例如显示不同的错误信息、提示信息等。
ApplicationContext是Spring框架中非常重要的一个组件,它提供了依赖注入、AOP、事件机制、资源管理、国际化支持等功能,使得开发人员可以更加方便地开发和管理应用程序。
spring为什么需要三级缓存?
Spring需要三级缓存是为了在bean的创建过程中保证单例的线程安全性。
第一级缓存是单例池,用于存放已经创建好的单例bean实例,当请求获取单例bean时,会从单例池中获取。
第二级缓存是早期单例对象缓存,用于存放正在创建中的单例bean实例,当第一次创建单例bean时,会将bean的创建过程放到早期单例对象缓存中,当后续再次请求获取该单例bean时,会从早期单例对象缓存中获取。
第三级缓存是单例工厂缓存,用于存放包含bean定义信息的ObjectFactory,当第一次请求获取单例bean时,会从单例工厂缓存中获取ObjectFactory,通过ObjectFactory创建bean实例并放入早期单例对象缓存中,当后续再次请求获取该单例bean时,会从早期单例对象缓存中获取。
通过这三级缓存的设计,可以保证在bean的创建过程中不会出现线程安全问题,并且能够在创建完成后快速获取单例bean实例。
spring如何实现AOP的?
Spring使用代理(Proxy)实现AOP。具体来说,Spring会根据配置的切点,在目标对象周围动态地生成一个代理对象,代理对象负责将切面逻辑织入到目标对象的执行流程中。
Spring中实现代理的方式有两种:JDK动态代理和CGLIB代理。JDK动态代理是通过反射机制来生成目标对象的代理对象,而CGLIB代理则是通过继承目标对象并重写其方法来生成代理对象。具体使用哪种代理方式,取决于被代理对象是否实现了接口。
Spring AOP的实现过程大致如下:
-
配置切面:通过定义切点和切面,告诉Spring需要在哪些目标对象的哪些方法周围织入切面逻辑。
-
生成代理对象:根据配置的切点和切面,使用JDK动态代理或CGLIB代理,在目标对象周围生成代理对象。
-
织入切面逻辑:在代理对象的方法执行前、执行后或抛出异常时,根据切面配置的通知类型,执行切面逻辑。
-
执行目标方法:调用代理对象的方法,实际执行的是目标对象的方法,并在执行流程中织入了切面逻辑。
Spring AOP通过代理实现了面向切面编程的功能,提供了一种灵活的方式来实现横切关注点的代码复用。
TODO 持续学习更新…