spring容器启动流程详解

准备工作:

@EnableAspectJAutoProxy
@Configuration
public class MyAopConfig {
    @Bean
    public MyAop yyAop() {
        return new MyAop();
    }
    @Bean
    public MyAspect myAspect() {
        return new MyAspect();
    }
}

@Test
public void test1() {
     AnnotationConfigApplicationContext applicationContext = 
        new AnnotationConfigApplicationContext(AopOneConfig.class);
     AopOne bean = applicationContext.getBean(AopOne.class);
     bean.compute(10, 1);
}

 一、一些基础的概念:

  • 1.1Spring的ioc(Inversion of Control)容器:

       Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。**在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:
        谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建**;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
        为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;**而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
        使用对象时候由主动new对象转换成由外部提供对象,此过程中对象的创建权由程序转移到外部,这种思想叫做控制反转;Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的外部,IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IOC容器中统称为Bean。

  • 1.2 BeanDefinition:

上面说的ioc容器存的是bean;当需要的时候可以直接从ioc容器中获取,那么这个bean就是我们写的类的实例对象么?其实不完全是,还是有区别
spring中的bean和普通Java类的实例的区别:

spring的bean比java类实例多出了,比如scope(作用域),isLazyInit(是否延迟初始化),isSingleton(是否单例)等属性特征,也就是说,普通的Java类是不能完整描述上面的属性的,那Spring就通过BeanDefinition这个类来描述普通的Java类的属性以及额外的cope(作用域),isLazyInit(是否延迟初始化),isSingleton(是否单例)等属性特征。spring就是根据BeanDefinition来实例化对应的bean。

  • 1.3 BeanDefinitionReader:

上面说了BeanDefinition类是用来描述普通的Java类的属性以及额外的cope(作用域),isLazyInit(是否延迟初始化),isSingleton(是否单例)等属性特征。

那总要有个能从我们配置的bean的地方获取这些属性的类吧,这个类就是BeanDefinitionReader。BeanDefinitionReader会将配置的bean解析成为BeanDefinition。

Spring Bean的配置方式有很多种,如XML,groovy,注解(可能通过properties,groovy的方式你不常用,但Spring确实支持这种方式),所以BeanDefinitionReader的实现类也很多:

1.4 BeanDefinitionRegistry:

BeanDefinitionReader将配置的bean解析成beanDefinition,需要将beanDefinition保存到BeanDefinitionRegistry中,相当于将工厂中的仓库,便于工厂的后续流程处理

1.5 BeanFactory:

根据beanDefinition建将bean生成出来,并且保存下来

1.6 DefaultListableBeanFactory:

DefaultListableBeanFactory它是大多数场景默认的beanFactory实现类,它实现了BeanDefinitionRegistry接口和BeanFactory接口,所以能保存Bean定义,同时又能根据Bean定义将Bean生产出来。

1.7 BeanPostProcessor

BeanFactory根据BeanDefinition生成Bean的过程是一个标准化的流程,就像一个流水线一样,当然你可以在这个流水线上做一些自定义的操作。

在Spring中你可以通过实现BeanPostProcessor来干预Bean的生产过程,所以这个BeanPostProcessor很重要,比如AOP等都是利用这个进行实现的。

BeanPostProcessor 可以在bean的初始化前后进行自定义的处理。可以参考:

sprig中怎么指定一个bean的初始化和销毁方法?一下子都搞懂! 第四节

1.8 BeanFactoryPostProcessor

Spring作为一个强大的容器,不仅能让你干预Bean的生产过程,还可以让你干预BeanFactory,例如你可以通过BeanFactoryPostProcessor将Bean的作用域都该成原型,默认是单例。

1.9  父 BeanFactory —— ParentBeanFactory

在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”。

在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

1.10  spring中的几个重要的缓存:

mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。 beanDefinitionMap 缓存:beanName -> BeanDefinition。 singletonObjects 缓存:beanName -> 单例 bean 对象。 earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成只是实例化有个引用,还未进行属性填充、初始化。 singletonFactories 缓存:beanName -> ObjectFactory。 singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。

二、Spring容器启动流程

spring容器启动流程主要包含两个过程:容器初始化、容器刷新

我们常用的容器有如下两种:

1.基于xml配置bean(ClassPathXmlApplicationContext)

2.基于注解配置bean(AnnotationConfigApplicationContext)

我们以AnnotationConfigApplicationContext启动流程为例:

@Repository
public class UserDao {
 public String getUser() {
  return "user";
 }
}
@Configuration
@ComponentScan("com.javashitang")
public class AppTestConfig {
}
public class Main {
 public static void main(String[] args) {
  // 容器启动完毕
  AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppTestConfig.class);
  UserDao userDao = context.getBean(UserDao.class);
  String str = userDao.getUser();
  System.out.println(str);
 }
}

当AnnotationConfigApplicationContext被new出来的时候,容器已经启动完毕,后续就可以直接从容器中获取Bean了

AnnotationConfigApplicationContext继承关系:

 构造函数里面类容:

 

2.1 容器初始化过程 —— this()

public AnnotationConfigApplicationContext() {
	StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
	this.reader = new AnnotatedBeanDefinitionReader(this);
	createAnnotatedBeanDefReader.end();
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

2.1.1 AnnotatedBeanDefinitionReader(this):

/**AnnotatedBeanDefinitionReader类中**/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}
/**下面是有参构造器,上面this方法调用这个**/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

2..1.2  AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);往下追到了下面方法:

/**
下面中注册internal的类,他们正真对应就是去掉internal这个前缀之后的类
**/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
	//ConfigurationAnnotationProcessor:它实现了BeanFactoryPostProcessor,处理@Configuration,@ComponmentScan等注解,这是一个很重要的类,主要用来解析我们主配置类(AppTestConfig)的
	if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
	}
	//实现了BeanPostProcessor,处理@Autowired,@Value等
	if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
	}

	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	//实现了BeanPostProcessor,用来处理JSR-250规范的注解,如@Resource,@PostConstruct等
	if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
	}

	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	//实现了BeanFactoryPostProcessor,用来支持JPA,在我们这个Demo中不会注册,因为路径中没有JPA相关的类
	if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {
		RootBeanDefinition def = new RootBeanDefinition();
		try {
			def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor",
					AnnotationConfigUtils.class.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Cannot load optional framework class: " + "org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", ex);
		}
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
	}
	//实现了BeanFactoryPostProcessor
	if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {
		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
	}

	if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {
		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
	}
	return beanDefs;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值