IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring的registerPostProcessor方法、refresh方法、加载和后置处理postprocess处理器源码带注释解析 -> 正文阅读

[Java知识库]spring的registerPostProcessor方法、refresh方法、加载和后置处理postprocess处理器源码带注释解析

BeanDefinition是什么?

在这里插入图片描述
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
AttributeAccessor接口:提供对BeanDefinition属性操作能力,
在这里插入图片描述
它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是否懒加载,是否Primary等等

registerPostProcessor方法:

private static BeanDefinitionHolder registerPostProcessor(
        BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(beanName, definition);
    return new BeanDefinitionHolder(definition, beanName);
}

这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定义的,然后又调用了registerBeanDefinition方法,再点进去,你会发现它是一个接口,没办法直接点进去了,首先要知道registry实现类是什么,那么它的实现是什么呢?答案是DefaultListableBeanFactory:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }

这又是一个门面方法,再点进去,核心在于下面两行代码:

//beanDefinitionMap是Map<String, BeanDefinition>,
//这里就是把beanName作为key,ScopedProxyMode作为value,推到map里面
this.beanDefinitionMap.put(beanName, beanDefinition);

//beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去
this.beanDefinitionNames.add(beanName);

从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,里面放着beanDefinitionMap,beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作为Value,beanDefinitionNames是一个集合,里面存放了beanName。
DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是相当重要的,以后会经常看到它,最好看到它,第一时间就可以反应出它里面放了什么数据
这里仅仅是注册,可以简单的理解为把一些原料放入工厂,工厂还没有真正的去生产
上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)就是BeanDefinitionRegistryPostProcessor Bean
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类,必须牢牢的记住上面所说的这个类和它的继承关系。
在这里插入图片描述

refresh方法:

类AbstractApplicationContext中
第516行
在这里插入图片描述
【 prepareRefresh】
从命名来看,就知道这个方法主要做了一些刷新前的准备工作,和主流程关系不大,主要是保存了容器的启动时间,启动标志等。
【ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()】
这个方法和主流程关系也不是很大,可以简单的认为,就是把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition
【prepareBeanFactory】

//还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector
//还设置了 忽略自动装配 和 允许自动装配 的接口,如果不存在某个bean的时候,spring就自动注册singleton bean
//还设置了bean表达式解析器 等
prepareBeanFactory(beanFactory);
/**
	 * IOC 容器的刷新
	 */
	public Collection<ApplicationListener<?>> getApplicationListeners() {
		return this.applicationListeners;
	}

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//1:准备刷新上下文环境
			prepareRefresh();

			//2:获取告诉子类初始化Bean工厂  不同工厂不同实现
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//3:对bean工厂进行填充属性
			prepareBeanFactory(beanFactory);

			try {
				// 第四:留个子类去实现该接口
				postProcessBeanFactory(beanFactory);

				// 调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition  2.bean工厂的后置处理器调用
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册我们bean的后置处理器
				registerBeanPostProcessors(beanFactory);

				// 初始化国际化资源处理器.
				initMessageSource();

				// 创建事件多播器
				initApplicationEventMulticaster();

				// 这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
				onRefresh();

				//把我们的事件监听器注册到多播器上
				registerListeners();

				// 实例化我们剩余的单实例bean.
				finishBeanFactoryInitialization(beanFactory);

				// 最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception  encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

prepareRefresh方法:

/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	protected void prepareRefresh() {
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		/**
		 *相传该方法在网上很多人说该方法没有用,因为这个方法是留个子类实现的,由于是对spring源码的核心
		 * 设计理念没有弄清楚,正式由于spring提供了大量的可扩展的接口提供给我们自己来实现
		 * 比如我们自己写一个类重写了initPropertySources方法,在该方法中设置了一个环境变量的值为A
		 * 启动的时候,我的环境变量中没有该值就会启动抛出异常
		 */
		initPropertySources();

		/**
		 * 用来校验我们容器启动必须依赖的环境变量的值
		 */
		getEnvironment().validateRequiredProperties();

		/**
		 * 创建一个早期事件监听器对象
		 */
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		/**
		 * 创建一个容器用于保存早期待发布的事件集合
		 * 什么是早期事件?
		 * 就是我们的事件监听器还没有注册到多播器上的时候都称为早期事件
		 * 早期事件不需要手动publishEvent发布, 在registerListeners中会自动发布, 发布完早期事件就不存在了。
		 */
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

	/**
	 * <p>Replace any stub property sources with actual instances.
	 * @see org.springframework.core.env.PropertySource.StubPropertySource
	 */
	protected void initPropertySources() {
		// For subclasses: do nothing by default.
	}

prepareBeanFactory:


	/**
	 * 为我们的bean工厂填充内部属性
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//设置bean工厂的类加载器为当前application应用的加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		//为bean工厂设置我们标准的SPEL表达式解析器对象StandardBeanExpressionResolver
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//为我们的bean工厂设置了一个propertityEditor 属性资源编辑器对象(用于后面的给bean对象赋值使用)
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		//注册了一个完整的ApplicationContextAwareProcessor 后置处理器用来处理ApplicationContextAware接口的回调方法
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));


		/**
		 *
		 * 忽略以下接口的bean的 接口函数方法。 在populateBean时
		 * 因为以下接口都有setXXX方法, 这些方法不特殊处理将会自动注入容器中的bean
		 */
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		/**
		 * 当注册了依赖解析后,例如当注册了对 BeanFactory.class 的解析依赖后,
		 * 当 bean 的属性注 入的时候, 一旦检测到属性为 BeanFactory 类型便会将 beanFactory 的实例注入进去。
		 * 知道为什么可以
		 * @Autowired
		 * ApplicationContext  applicationContext  就是因为这里设置了
		 */
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		//注册了一个事件监听器探测器后置处理器接口
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 处理aspectj的
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		//注册了bean工厂的内部的bean
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			//环境
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			//环境系统属性
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			//系统环境
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

BeanDefinition读取器: AnnotatedBeanDefinitionReader:

其主要做了2件事情
1.注册内置BeanPostProcessor
2.注册相关的BeanDefinition
让我们把目光回到AnnotationConfigApplicationContext的无参构造方法,让我们看看Spring在初始化AnnotatedBeanDefinitionReader的时候做了什么:


 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }

这里的BeanDefinitionRegistry当然就是AnnotationConfigApplicationContext的实例了,这里又直接调用了此类其他的构造方法:

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);
}

让我们把目光移动到这个方法的最后一行,进入

registerAnnotationConfigProcessors方法:
    public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        registerAnnotationConfigProcessors(registry, null);
    }

这又是一个门面方法,再点进去,这个方法的返回值Set,但是上游方法并没有去接收这个返回值,所以这个方法的返回值也不是很重要了,当然方法内部给这个返回值赋值也不重要了。由于这个方法内容比较多,这里就把最核心的贴出来,这个方法的核心就是注册Spring内置的多个Bean:

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
     RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
     def.setSource(source);
     beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类
执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册其他Bean也是一样的流程。

AnnotationConfigUtils类的registerAnnotationConfigProcessors

在这个类中注册了configurationclasspostprocessor
【如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例】

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				//注册了实现Order接口的排序器
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			//设置@AutoWired的候选的解析器:ContextAnnotationAutowireCandidateResolver
			// getLazyResolutionProxyIfNecessary方法,它也是唯一实现。
			//如果字段上带有@Lazy注解,表示进行懒加载 Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		/**
		 * 为我们容器中注册了解析我们配置类的后置处理器ConfigurationClassPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器中注册了处理@Autowired 注解的处理器AutowiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器中注册处理@Required属性的注解处理器RequiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalRequiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor
		 * org.springframework.context.annotation.internalCommonAnnotationProcessor
		 */
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理jpa注解的处理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
		 */
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理监听方法的注解@EventListener解析器EventListenerMethodProcessor
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 注册事件监听器工厂
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

实例化容器:AnnotationConfigApplicationContext :

是上面AbstractApplicationContext类的子类
AnnotationConfigApplicationContext 是以注解的方式解析bean,类图:
在这里插入图片描述
假设有一个启动类:

	public static void main(String[] args)   {
		// 加载spring上下文
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

		Car car =  (Car) context.getBean("car");
		System.out.println(car.getName());
	}

查看AnnotationConfigApplicationContext对象部分源码:

//无参构造方法:
	public AnnotationConfigApplicationContext() {
		/**
		 * 创建一个读取注解的Bean定义读取器
		 * 什么是bean定义?BeanDefinition
		 * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
		 */
		this.reader = new AnnotatedBeanDefinitionReader(this);
		/**
		 * 创建BeanDefinition扫描器
		 * 可以用来扫描包或者类,继而转换为bd
		 * spring默认的扫描包不是这个scanner对象
		 * 而是自己new的一个ClassPathBeanDefinitionScanner
		 * spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner		 
		 * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

//根据参数类型可以知道,其实可以传入多个annotatedClasses,但是这种情况出现的比较少
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
        //父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory
        //本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner
        //scanner的用处不是很大,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的
        this();
        //把传入的类进行注册,这里有两个情况,
        //传入传统的配置类
        //传入bean(虽然一般没有人会这么做
        //看到后面会知道spring把传统的带上@Configuration的配置类称之为FULL配置类,不带@Configuration的称之为Lite配置类
        //但是我们这里先把带上@Configuration的配置类称之为传统配置类,不带的称之为普通bean
        register(annotatedClasses);
        //刷新
        refresh();
    }

我们先来为构造方法做一个简单的说明:
这是一个有参的构造方法,可以接收多个配置类,不过一般情况下,只会传入一个配置类。
这个配置类有两种情况,一种是传统意义上的带上@Configuration注解的配置类,还有一种是没有带上@Configuration,但是带有@Component,@Import,@ImportResouce,@Service,@ComponentScan等注解的配置类,在Spring内部把前者称为Full配置类,把后者称之为Lite配置类。在本源码分析中,有些地方也把Lite配置类称为普通Bean。
在构造方法

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}

中注册了很多后置处理器

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
		this.registry = registry;
		//用户处理条件注解 @Conditional os.name
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		//注册一些内置的后置处理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

register方法

在下面register方法中注册了很多bean定义,解析了带configuration注解的配置类:

	@Override
	public void register(Class<?>... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
		this.reader.register(annotatedClasses);
	}

register的具体实现在类AnnotatedBeanDefinitionReader中

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//存储@Configuration注解注释的类
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		//判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		//解析bean的作用域,如果没有设置的话,默认为单例
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		//获得beanName
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

		//注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
		//DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
		//beanDefinitionNames是一个List<String>,用来保存beanName
		//beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

实例化工厂:DefaultListableBeanFactory中注册bean的方法:

在这里插入图片描述

类上加configuration类的作用:

spring对于加了configuration的类会生成一个cglib动态代理,例如:

@Component
@Data
public class Tank  {


	private Integer index;

	private String name;
	public Tank() {
		System.out.println("tank加载");
	}



}

然后另外一个类:
在 car.setTank(tank());这个方法中
// 如果不去ioc 容器中拿 ,每次都会创建新的Tank
如果加锁了@Configuration,就会从单例池中拿tank这个bean

@Configuration
@ComponentScan(basePackages = {"com.tuling.iocbeanlifecicle"})
        //excludeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION,value={Controller.class})})

public class MainConfig {

    @Bean("car")
    public Car car(){

        Car car = new Car();
        car.setName("xushu");
        car.setTank(tank());
    
        return car;
    }

    @Bean
    public Tank tank(){
        return new Tank();
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 22:56:59  更:2022-01-29 22:58:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 13:30:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码