阅读 125

源码解析:Spring源码解析笔记(一)

Spring源码解析笔记(一)

本文由colodoo(纸伞)整理

QQ 425343603

Java学习交流群(717726984)

参考 www.bilibili.com/video/BV1dK… 1-10章节

BeanDefinition

BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念。

@Component、@Bean、都会被解析成BeanDefinition。

配置属性包含

  • beanClass
  • scope
  • isLazy
  • dependsOn
  • primary
  • initMethodName

beanClass

表示一个bean的类型,比如UserService.class、OrderService.class,Spring在创建Bean 的过程中会根据此属性来实例化得到对象。

scope

表示一个bean的作用域,比如:

scope等于singleton,该bean就是一个单例Bean;

scope等于prototype,该bean就是一个原型bean。

isLazy

表示一个bena是不是需要懒加载,原型bean的isLazy属性不起作用,懒加载的单例bean,会在第一次getBean的时候生成该bean,非懒加载的单例bean,则会在Spring启动过程中直接生成好。

dependsOn

表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它错依赖的这些bean得先全部创建好。

primary

表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性。

initMethodName

表示一个bean得初始化方法,一个bean的生命周去过程中有一个步骤叫初始化,Spring会在这个步骤中取调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工。

BeanFactory

BeanFactory是一种“Spring容器”,BeanFactory翻译过来就是Bean工厂;它可以用来创建Bean、获取Bean,BeanFactory是Spring中非常核心的组件。

BeanDefintion、BeanFactory、Bean 关系

BeanFactory将利用BeanDefinition来生成Bean对象,BeanDefinition相当于BeanFactory的原材料,Bean对象就相当于BeanFactory所生产出来的产品。

BeanFactory利用BeanDefinition产出Bean对象。

核心子接口和实现类

  • ListableBeanFactory
  • ConfigurableBeanFactory
  • AuwowireCapableBeanFactory
  • AbstractBeanFactory
  • DefaultListableBeanFactory

DefaultListableBeanFactory

支持单例Bean、支持Bean别名、支持父子BeanFactory、支持Bean类型转化、支持Bean后置处理、支持FactoryBean、支持自动装配,等等。

Bean生命周期

生命周期的几个阶段:

  • BeanDefinition -> Bean定义
  • 构造方法推断 -> 选出构造方法
  • 实例化 -> 构造方法反射实例化对象
  • 属性填充 -> 自动填充属性
  • 初始化 -> 对其他属性赋值、校验
  • 初始化后 -> AOP、生成代理对象

BeanDefinition

BeanDefinition表示Bean定义,它定义了某个Bean的类型,Spring就是利用BeanDefinition来创建Bean的,比如需要利用BeanDefinition中beanClass属性确定Bean的类型,从而实例化出来对象。

构造方法推断

一个Bean中可以有多个构造方法,此时就需要Spring来判断到底使用哪个构造方法,这个过程是比较复杂的,篇幅有限,不展开介绍。通过构造方法推断之后确定一个构造方法后,就可以利用构造方法实例化得到一个对象了。

实例化

通过构造方法反射得到一个实例化对象,在Spring中,可以通过BeanPostProcessor机制对实例化进行干预。

属性填充

实例化所得到的对象,是“不完整”的对象,“不完整”的意思是该对象中的某些属性还没有进行属性填充,也就是Spring还没有自动给某些属性赋值,属性填充就是我们通常说的自动注入、依赖注入。

初始化

在一个对象的属性填充之后,Spring提供了初始化机制,程序员可以利用初始化机制对Bean进行自定义加工,比如可以利用InitializingBean接口来对Bean中的其他属性进行赋值,或对Bean中的某些属性进行校验。

@Autowired

@Autowired表示某个属性是否需要进行依赖注入,可以写在属性和方法上。注解中的required属性默认为true,表示如果没有对象可以注入给属性则抛异常。

@Service
public class OrderService {
    
    @Autowired
    private UserService userService;
    
}
复制代码

@Autowired加在某个属性上,Spring在进行Bean的生命周期过程中,在属性填充这一步,会基于实例化出来的对象,对该对象中加了@Autowired的属性自动给属性赋值。

Tip:操作步骤是在属性填充这一步。

构造方法

@Autowired加在构造方法上时,Spring会在推断构造方法阶段,选择该构造方法来进行实例化,在反射调用构造方法之前,会先根据构造方法参数类型、参数名从Spring容器中找到Bean对象,当作构造方法入参。

@Resource

@resource如果name属性有值,那么Spring会直接根据所指定的name值取Spring容器找Bean对象,如果找到了则成功,没有找到则报错。

@Value

@Value注解和@Resource、@Autowired类似,也是用来对属性进行依赖注入的,只不过@Value是用来从Properties文件中获取值的,并且@Value可以解析SpEL(Spring表达式)。

FactoryBean

FactoryBean是Spring所提供的一种较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象。

接口方法:

  • Object getObject():返回的是Bean对象
  • boolean isSingleton():返回的是否是单例Bean对象
  • Class getObjectType():返回的是Bean对象的类型

代码:

@Component( "demo")
public class DemoFactoryBean implements FactoryBean {
    
	@Override
    public 0bject get0bject() throws Exception {
    	return new Demo();
    }
    @Override
    public class<?> get0bjectType() {
    	return Demo.class;
    }
	@Override
	//所定义的Bean是单例还是原型
	public boolean issingleton() {
		return true;
	}
}
复制代码

FactoryBean机制被广泛的应用在Spring内部和Spring与第三方框架或组件的整合过程中。

FactoryBean和BeanFactory

FactoryBean

FactoryBean对象本身也是一个Bean,同事它相当于一个小型工厂,可以生产出另外的Bean。

BeanFactory

BeanFactory是一个Spring容器,是一个大型工厂,它可以生产出各种各样的Bean。

ApplicationContext

ApplicationContext是比BeanFactory更加强大的Spring容器,它既可以创建bean、获取bean,还支持国际化、事件广播、获取资源等BeanFactory不具备的功能。

继承接口

  • EnvironmentCapable
  • ListableBeanFactory
  • HierarchicalBeanFactory
  • MessageSource
  • ApplicationEventPublisher

BeanPostProcessor

BeanPostProcessor在Spring中是一个接口,我们定义一个后置执行器,就是提供一个类实现该接口,在Spring中还存在一些接口继承了BeanPostProcessor,这些接子接口是在BeanPostProcessor的基础上增加了一些其他的功能。

BeanPostProcessor中的方法

postProcessBeforelnitialization():初始化前方法,表示可以利用这个方法来对Bean在初始化前进行自定义加工。

postProcessAfterlnitialization):初始化后方法,表示可以利用这个方法来对Bean在初始化后进行自定义加工。

InstantiationAwareBeanPostProcessor

BeanPostProcessor的一个子接口, postProcessBeforelnstantiation():实例化前

postProcessAfterlnstantiation():实例化后postProcessProperties():属性注入后

AOP

Aop就是面向切面编程,是一种非常适合在无需修改业务代码的前提下,对某个或某些业务增加统一的功能,比如日志记录、权限重置、事务管理等,能很好的使得代码解耦,提高开发效率。

  • Advice
  • Pointcut
  • Advisor
  • Weaving
  • Target
  • Join Point

Advice

Advice可以理解为通知、建议,在Spring中通过定义Advice来定义代理逻辑。

Pointcut

Pointcut是切点,表示Advice对应的代理逻辑应用在哪个类、哪个方法上。

Advisor

Advisr等于Advice+Pointcut,表示代理逻辑和切点的一个整体,程序员可以通过定义或封装一个Advisor,来定义切点和代理逻辑。

Weaving

Weaving表示织入,将Advicedialing逻辑在源代码级别嵌入到切面得过程,就叫做织入。

Target

Target表示目标对象,也就是被代理对象,在AOP生成的代理对象中对持有目标对象。

Join Point

Join Point表示连接点,在Spring AOP中,就是方法的执行点。

AOP工作原理

AOP是发生在Bean的生命周期过程中的;

  • Spring生成bean对象时,先实例化出来一个对象,也就是target对象。
  • 再对target对象进行属性填充。
  • 在初始化步骤中,会判断target对象有没有对应的切面。
  • 如果有切面,就表示当前target对象需要进行AOP。
  • 通过Cglib或JDK动态代理机制生成一个代理对象,作为最终的bean对象。
  • 代理对象中有一个target属性只想了target对象。
文章分类
后端
文章标签