Spring框架之底层架构核心概念解析

系列文章目录

例如:第一章 Python 机器学习入门之pandas的使用



前言

温馨提示:本篇文章Spring框架源码是依赖于5.3.10版本的:

在看Spring源码之前,我们应当先熟悉Spring底层有哪些核心依赖接口,可以做什么,才好未来在工作当中,或者自己开发中间件更好的利用Spring框架。


一、BeanDefintion

BeanDefintion是一个接口 ,,它表示一个Bean的定义 ,BeanDefintion存在很多属性来描述一个Bean的特点 ,比如

  • beanClassName:bean的class类型名称
  • scope:单例模式 原型模式
  • lazyInit:是否懒加载
  • dependsOn
  • autowireCandidate:按照类型装配作为候选者
  • primary:是否主要
  • factoryBeanName:factoryBean的名称
  • InitMethodName:初始化方法

Spring在扫描的时候需要注册的Bean之后会进行解析 , 而解析的数据就会生成BeanDefintion,同时存到BeanDefintionMap当中
我们在定义Bean的时候可以分为两种方式 :

声明式
申明式定义一个Bean就比如我们用的@Bean , @Component等注解 , 或者是xml标签的形式来定义一个Bean

编程式
就是写代码的方式生成一个bean。

public class OrderService {

    public void test(){
        System.out.println("bean调用成功");
    }
}
@ComponentScan(basePackages = {"com.lautos"})
public class AppConfig {
}
public class TestDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

//        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
//        beanDefinition.setBeanClass(OrderService.class);
//        beanDefinition.setScope("prototype");
//
//        context.registerBeanDefinition("orderService", beanDefinition);

        OrderService orderService1 = (OrderService) context.getBean("orderService");
        OrderService orderService2 = (OrderService) context.getBean("orderService");
        System.out.println(orderService1);
        System.out.println(orderService2);

        orderService1.test();
        orderService2.test();

    }
}

没有打开注释,也未声明注解,则会报错:No bean named ‘orderService’ available

打开注释后,打印效果如图所示
在这里插入图片描述

二、BeanDefinitionReader

接下来,我们来介绍几种在Spring源码中所提供的BeanDefinition读取器(BeanDefinitionReader),这些BeanDefinitionReader在我们使用Spring时用得少,但在Spring源码中用得多,相当于Spring源码的基础设施。

1.AnnotatedBeanDefinitionReader

可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,代码如下(示例):

public class TestDemo {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

		AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);

		// 将User.class解析为BeanDefinition
		annotatedBeanDefinitionReader.register(User.class);
		System.out.println(context.getBean("user"));
	}
}

注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description

2.XmlBeanDefinitionReader

可以解析xml标签,代码如下(示例):

代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"
>

	<context:component-scan base-package="com.lotus"/>
	<bean id="user" class="com.lotus.service.User"/>
</beans>
public class TestDemo {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

		XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
		int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");

		System.out.println(context.getBean("user"));
	}
}

3.ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner是扫描器,但是它的作用和BeanDefinitionReader类似,它可以进行扫描某个包路径,对扫描到的类进行解析,比如,扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition,比如:,代码如下(示例):

代码如下(示例):

public class TestDemo {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.refresh();

		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
		scanner.scan("com.lotus");

		System.out.println(context.getBean("userService"));
	}
}

三、BeanFactory

BeanFactory表示Bean工厂,所以很明显,BeanFactory会负责创建Bean,并且提供获取Bean的API。
而ApplicationContext是BeanFactory的一种,在Spring源码中,是这么定义的:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}

1.DefaultListableBeanFactory

在spring源码当中DefaultListableBeanFactory这个类是很重要的,实现了很多接口和抽象类,掌握这个很重要。我们可以看下它的结构图:

在这里插入图片描述它实现了很多接口,表示,它拥有很多功能:

  • AliasRegistry:支持别名功能,一个名字可以对应多个别名
  • BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition
  • BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象
  • SingletonBeanRegistry:可以直接注册、获取某个单例Bean
  • SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能
  • ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的Bean}的映射关系
  • HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
  • DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能
  • ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能
  • FactoryBeanRegistrySupport:支持了FactoryBean的功能
  • AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配
  • AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和获取beanNames
  • ConfigurableListableBeanFactory:继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory
  • AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能
  • DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

2.ApplicationContext

上面有分析到,ApplicationContext是个接口,实际上也是一个BeanFactory,不过比BeanFactory更加强大,比如:

  1. HierarchicalBeanFactory:拥有获取父BeanFactory的功能
  2. ListableBeanFactory:拥有获取beanNames的功能
  3. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
  4. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
  5. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
  6. MessageSource:拥有国际化功能

总结

例如:以上就是今天要讲的内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白努力学java

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

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

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

打赏作者

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

抵扣说明:

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

余额充值