Spring 5.2.9 07 源码分析-spring的bean工厂准备工作(上)

完整路径:

调用setText方法

//程序入口
MyClassPathXmlApplicationContext.MyClassPathXmlApplicationContext(String... configLocations){}
ClassPathXmlApplicationContext(String... configLocations) throws BeansException {}
ClassPathXmlApplicationContext.ClassPathXmlApplicationContext(String... configLocations) throws BeansException {}
this(configLocations, true, null);
		#重复方法, enter
		this(configLocations, true, null);
			refresh();
#spring核心代码#refresh();
//Spring源码核心,所有初始化信息的加载过程在全部都在这里。
				// 初始化剩下的单实例(非懒加载的)
				finishBeanFactoryInitialization(beanFactory);
		#方法调用
		// 实例化剩下的单例对象
		beanFactory.preInstantiateSingletons();
ConfigurableListableBeanFactory.preInstantiateSingletons() throws BeansException;
DefaultListableBeanFactory.preInstantiateSingletons() throws BeansException {}
					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
AbstractBeanFactory.getBean(String name) throws BeansException {}
		// 此方法是实际获取bean的方法,也是触发依赖注入的方法
		return doGetBean(name, null, null, false);
							#方法调用
							// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
							return createBean(beanName, mbd, args);
AbstractBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException;
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 实际创建bean的调用
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			#方法调用beanName.equals("customer"),此处是 循环执行,需要等对象是customer才是自定义解析器。
			// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
			#方法调用
			//应用给定的属性值,解决任何在这个bean工厂运行时其他bean的引用。必须使用深拷贝,所以我们 不会永久地修改这个属性
			applyPropertyValues(beanName, mbd, bw, pvs);
					#方法调用propertyName.equals("address"),此处是 循环执行,需要等对象是customer才是自定义解析器。
					//将resolvedValue转换为指定的目标属性对象
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			#方法调用
			return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
BeanWrapperImpl.convertForProperty(@Nullable Object value, String propertyName) throws TypeMismatchException {}
		return convertForProperty(propertyName, null, value, td);
AbstractNestablePropertyAccessor.convertForProperty(
			String propertyName, @Nullable Object oldValue, @Nullable Object oldValue, TypeDescriptor td)
			throws TypeMismatchException {}
		return convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
			#调用方法
			return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td);
TypeConverterDelegate.convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
			@Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {}
			// 使用editor将convertedValue转换为requiredType
			convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
				#方法调用
				// 使用editor转换newTextValue,并将转换后的值返回出去
				return doConvertTextValue(oldValue, newTextValue, editor);
		#方法调用
		// 使用newTextValue更新内部属性值
		editor.setAsText(newTextValue);
#路径结束#自定义属性解析器
AddressPropertyEditor.setAsText(String text) throws IllegalArgumentException {}
//程序入口
MyClassPathXmlApplicationContext.MyClassPathXmlApplicationContext(String... configLocations){}
ClassPathXmlApplicationContext(String... configLocations) throws BeansException {}
ClassPathXmlApplicationContext.ClassPathXmlApplicationContext(String... configLocations) throws BeansException {}
this(configLocations, true, null);
		#重复方法, enter
		this(configLocations, true, null);
			refresh();
#spring核心代码#refresh();
//Spring源码核心,所有初始化信息的加载过程在全部都在这里。
				// 初始化剩下的单实例(非懒加载的)
				finishBeanFactoryInitialization(beanFactory);
		#方法调用
		// 实例化剩下的单例对象
		beanFactory.preInstantiateSingletons();
ConfigurableListableBeanFactory.preInstantiateSingletons() throws BeansException;
DefaultListableBeanFactory.preInstantiateSingletons() throws BeansException {}
					// 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
AbstractBeanFactory.getBean(String name) throws BeansException {}
		// 此方法是实际获取bean的方法,也是触发依赖注入的方法
		return doGetBean(name, null, null, false);
							#方法调用
							// 为给定的合并后BeanDefinition(和参数)创建一个bean实例
							return createBean(beanName, mbd, args);
AbstractBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException;
AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 实际创建bean的调用
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	#方法调用
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {}
			// 根据执行bean使用对应的策略创建新的实例,如,工厂方法,构造函数主动注入、简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		#调用方法
		// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
		return instantiateBean(beanName, mbd);
			#调用方法
			// 包装成BeanWrapper
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
####读取解析器Edidor####代码分支
			#initBeanWrapper(bw);
BeanWrapperImpl.BeanWrapperImpl(Object object) {}
		super(object);
AbstractNestablePropertyAccessor.AbstractNestablePropertyAccessor(Object object) {}
		registerDefaultEditors();
#路径结束#
PropertyEditorRegistrySupport.registerDefaultEditors() {}
		this.defaultEditorsActive = true;
####################################################################
####读取解析器Edidor####代码分支
			#BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
		#方法调用
		// 将工厂中所有PropertyEditor注册到bw中
		registerCustomEditors(bw);
					#方法调用
					// 将registrar中的所有PropertyEditor注册到PropertyEditorRegistry中
					registrar.registerCustomEditors(registry);
#路径结束#
ResourceEditorRegistrar.registerCustomEditors(PropertyEditorRegistry registry) {}

相关类
调用方法

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置beanfactory的表达式语言处理器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	}
解析表达式#{}
package org.springframework.context.expression;
StandardBeanExpressionResolver.java

调用方法

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具类
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
}

注册解析器Editor
package org.springframework.beans.support
ResourceEditorRegistrar

public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
	@Override
	public void registerCustomEditors(PropertyEditorRegistry registry) {
		ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
		doRegisterEditor(registry, Resource.class, baseEditor);
		doRegisterEditor(registry, ContextResource.class, baseEditor);
		doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
		doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
		doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
		doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
		doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
		doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));

		ClassLoader classLoader = this.resourceLoader.getClassLoader();
		doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
		doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
		doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));

		if (this.resourceLoader instanceof ResourcePatternResolver) {
			doRegisterEditor(registry, Resource[].class,
					new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
		}
	}
}


备注:
beanName.equals(“customer”),此处是 循环执行,需要等对象是customer才是自定义解析器。

package org.springframework.beans.factory.support
AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
}

propertyName.equals(“address”),此处是 循环执行,需要等对象是customer才是自定义解析器。

package org.springframework.beans.factory.support
AbstractAutowireCapableBeanFactory.java
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//将resolvedValue转换为指定的目标属性对象
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}

调试操作:
第一次进入调试,只有保留beanName和propertyName入口代码的注释。进入了propertyName.equals(“address”);逻辑后开启所有注释。
在这里插入图片描述

spring 5.2.9 07 源码分析-spring的bean工厂准备工作 断点注释
https://download.csdn.net/download/weixin_50750933/85749549

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 Play Framework、MyBatis-Plus 和 Spring 集成起来,可以按照以下步骤进行操作: 1. 添加 MyBatis-Plus 和 Spring 依赖项到 Play Framework 项目中。 ``` libraryDependencies ++= Seq( "com.baomidou" %% "mybatis-plus" % "3.4.2", "org.springframework" % "spring-context" % "5.2.9.RELEASE" ) ``` 2. 创建一个 Spring Context 配置文件,例如 applicationContext.xml,并在文件中配置 MyBatis-Plus 和数据源。 ```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:mybatis-plus="http://mybatis.org/schema/mybatis-plus" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-plus http://mybatis.org/schema/mybatis-plus/mybatis-plus.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- MyBatis-Plus 配置 --> <mybatis-plus:configuration> <mybatis-plus:global-config> <mybatis-plus:db-config id="dbConfig" /> </mybatis-plus:global-config> </mybatis-plus:configuration> <!-- 数据源配置 --> <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <!-- MyBatis-Plus SqlSessionFactory 配置 --> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="mapperLocations" value="classpath*:mapper/**/*.xml" /> <property name="globalConfig" ref="dbConfig" /> </bean> <!-- MyBatis-Plus MapperScannerConfigurer 配置 --> <bean class="com.baomidou.mybatisplus.extension.spring.MybatisMapperScannerConfigurer"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> </beans> ``` 3. 创建 MyBatis-Plus 配置文件,例如 mybatis-config.xml,并在文件中配置 MyBatis-Plus 的一些参数和插件。 ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <settings> <setting name="cacheEnabled" value="true" /> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false" /> </settings> <plugins> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor" /> </plugins> </configuration> ``` 4. 在 Play Framework 中,可以使用 SpringApplicationBuilder 创建 Spring Context,并将其与应用程序一起启动。 ```java package controllers; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import play.mvc.Controller; import play.mvc.Result; public class HomeController extends Controller { public Result index() { // 使用 SpringApplicationBuilder 创建 Spring Context ApplicationContext context = new AnnotationConfigApplicationContext(); context.registerShutdownHook(); // 或者使用 ClassPathXmlApplicationContext 加载 applicationContext.xml 文件 // ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取 MyBatis-Plus Mapper 接口实例 UserMapper userMapper = context.getBean(UserMapper.class); // 调用接口方法,执行 SQL 操作 User user = userMapper.selectById(1L); return ok(user.toString()); } } ``` 这样,就可以在 Play Framework 中集成 MyBatis-Plus 和 Spring 了。当然,还需要根据项目实际情况进行进一步的配置和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值