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

本文深入探讨Spring框架的底层架构,解析BeanDefinition的属性及其在申明式定义Bean中的应用,如、@Bean和@Component。接着介绍了BeanDefinitionReader的三种实现,包括AnnotatedBeanDefinitionReader、XmlBeanDefinitionReader和ClassPathBeanDefinitionScanner。此外,文章讲解了BeanFactory和ApplicationContext的概念及其关系,包括国际化、资源加载、事件发布等功能。最后,涉及了类型转化、OrderComparator以及MetadataReader等关键概念。
摘要由CSDN通过智能技术生成

BeanDefinition

BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点。比如:

  • class,表示Bean类型
  • scope,表示Bean作用域,单例或原型等
  • lazyInit:表示Bean是否是懒加载
  • initMethodName:表示Bean初始化时要执行的方法
  • destroyMethodName:表示Bean销毁时要执行的方法
  • 还有很多...

在Spring中,我们经常会通过以下几种方式来定义Bean:

  1. <bean/>
  2. @Bean
  3. @Component(@Service,@Controller)

这些,我们可以称之申明式定义Bean

我们还可以编程式定义Bean,那就是直接通过BeanDefinition,比如:

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

		// 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();

		// Bean类型
		beanDefinition.setBeanClass(User.class);

		// 作用域
		beanDefinition.setScope("singleton");
		// 懒加载
		beanDefinition.setLazyInit(true);

		// 注册bean定义 beanName和Bean类型
		context.registerBeanDefinition("user", beanDefinition);

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

 实际中用注解实现,底层是这么实现的。

BeanDefinitionReader

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

AnnotatedBeanDefinitionReader

可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,比如

	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"));
		User user = (User) context.getBean("user");
		user.test();
	}

比起上面的BeanDefinition,省去了很多代码。

register方法,底层是构造BeanDefinition,解析处理类上的注解。

 AnnotatedBeanDefinitionReader的构造器,this()方法,会创建AnnotatedBeanDefinitionReader。

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

XmlBeanDefinitionReader

可以解析<bean/>标签

	/**
	 * XmlBeanDefinitionReader 解析xml 配置的bean 不会扫描
	 * @param args
	 */
	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"));
		User user = (User) context.getBean("user");
		user.test();
	}

 i是数量,解析出来一个。

ClassPathBeanDefinitionScanner

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

	/**
	 * ClassPathBeanDefinitionScanner  BeanDefinition扫描器 扫描指定目录下@Component注解修饰的类 创建BeanDefinition bean对象
	 * @param args
	 */
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.refresh();

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

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

 

从源码可见,AnnotationConfigApplicationContext既有扫描又有直接注册功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值