spring注解版构造函数

spring注解版构造函数的流程解析

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
	}

今天要讲的就是this这个方法

一。this构造函数解析

public AnnotationConfigApplicationContext() {
		//TODO 每一个类的构造函数都会调用父类的构造函数,可能不会写super()显示调用,但是都会调用,这里使没有显示调用,隐式调用父类的方法
		/**
		 * 调用父类以及父类的父类的构造器,目前主要是创建一个DefaultListableBeanFactory 的bean工厂,还有就是获取类加载器(默认当前线程的类加载器)
		 */
		super();

		/**
		 * beanDefinitionReader接口,读取配置文件,转换成beanDefinition,这里是将标有@Service,@Component,等等注解的类的一些信息转换成beanDefinition类
		 * 该类记录了指定JavaBean的一些信息,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等
		 * 那么就需要一个注解配置读取器,来读取这些信息
		 */
		this.reader = new AnnotatedBeanDefinitionReader(this);

		/**
		 * 如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器BeanDefinitionScanner
		 * 专门用来扫描标有@Service,@Component 等等注解的JavaBean,然后通过AnnotatedBeanDefinitionReader来读取信息
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
  1. 这里首先声明一下,在Java中调用子类的构造方法时,也会显式或者隐式父类的构造方法
  2. 由于spring里面层级结构非常复杂,一个类有很多层的父类,就是父类有父类,父类的父类还有父类,等等,这时候如果想查看一个类的构造方法到底进行了那些操作,就必须一层一层的查看父类的构造函数(可能父类没有构造函数,父类还有父类,这时候编辑器会自动添加一个无参构造器,这个无参构造器也会调用父类的构造器,不要忘了,不然,有时候有些变量的值你都不知道什么时候出现赋值的)
  3. 所以我们一个一个的看父类的构造函数

1.1 GenericApplicationContext类构造函数

public GenericApplicationContext() {
		//todo,隐式调用父类的构造方法,去看看
		super();
		/**
		 * AnnotationConfigApplicationContext类首先通过调用父类构造器创建一个beanFactory工厂,专门用来生成bean对象
		 */
		this.beanFactory = new DefaultListableBeanFactory();
	}

这个构造函数主要式生成一个默认的bean工厂,用于生产bean,以及一些初始化属性

哎呀,算了,直接看看类关系图,其实这个this方法主要是进行一些初始化,比如资源加载器初始化,beanfactory初始化

AnnotationConfigApplicationContext的父类的父类关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fmqG1wGK-1611709461980)(image-20210123134816532.png)]

DefaultListableBeanFactory的父类构造函数关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yaDFZgXj-1611709461984)(image-20210123135027846.png)]

总之到this构造函数结束的时候,创建了一个beanfactory(默认的)以及资源加载器,还有更细节的暂时用不到,还有就是 AnnotationConfigApplicationContext 和bean工厂的一些属性的初始化操作

1.2 AnnotatedBeanDefinitionReader 读取JavaBean 的读取器的初始化操作

调用一个参数的构造方法

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		/**
		 * getOrCreateEnvironment(registry) 主要是创建环境变量对象,Environment,该变量包含一个spring项目所在的系统的信息以及属性
		 * 下面就是调用其他构造方法,进行构造,最主要的是给beanfactory创建6 个后置处理器
		 */
		this(registry, getOrCreateEnvironment(registry));
	}
getOrCreateEnvironment(registry)
这个方法主要是创建一个Environment 环境变量对象,默认创建一个StandardEnvironment对象,该对象最主要的是获取系统的环境变量,就是将
System.getProperties()
System.getenv()
这两个属性设置在StandardEnvironment对象中

再调用两个参数的构造函数

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);
		/**
		 * 注册6个后置处理器
		 */
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

上面这一步最主要的就是最后一步,向spring的beanfactory注册6个后置处理器

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

		//todo
		/**
		 * 获取beanfactory
		 */
		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());
			}
		}

		/**
		 * 设置BeanDefinitionHolder,主要是记录  beandefinition的别名,名字和JavaBean,这里主要是后置处理器
		 */
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		/**
		 * org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		 * 向beanfactory注册org.springframework.context.annotation.ConfigurationClassPostProcessor类
		 * 顺便设置该类的处理类BeanDefinitionHolder
		 */
		/**
		 * @Configuration 注解的解析器,即BeanFactoryPostProcessor,专门 用于处理@Configuration注解的工厂的后置处理器
		 * https://www.cnblogs.com/jiaoqq/p/7678037.html
		 */
		//todo
		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));
		}

		/**
		 * 注册org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		 * 对应的类org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
		 */
		/**
		 * 注册BeanPostProcessor 后置处理器,在JavaBean初始化前后调用,主要是处理@Autowired注解
		 * https://www.cnblogs.com/lzeffort/p/7748611.html
		 */
		//todo
		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));
		}

		/**
		 * org.springframework.context.annotation.internalCommonAnnotationProcessor
		 * org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
		 */
		/**
		 * 注册BeanPostProcessor,处理@EJB,@WebServiceRef,@Resource,@PreDestroy,@PostConstruct 注解的处理
		 * https://blog.csdn.net/shenchaohao12321/article/details/81235571
		 */
		//todo
		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		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));
		}

		/**
		 * org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
		 *
		 */
		// Check for JPA support, and if present add the 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));
		}

		/**
		 * org.springframework.context.event.internalEventListenerProcessor
		 * org.springframework.context.event.EventListenerMethodProcessor
		 */
		/**
		 * 对于@EventListener 注解的处理,BeanFactoryPostProcessor
		 * https://www.cnblogs.com/elvinle/p/13298007.html
		 */
		//todo
		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));
		}

		/**
		 * org.springframework.context.event.internalEventListenerFactory
		 * org.springframework.context.event.DefaultEventListenerFactory
		 */
		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;
	}

执行完上面这一步,spring容器中的beanDefinitionMap就会出现 5 个beanDefinition。

beanDefinition 只是记录某个JavaBean的信息,并没有实例化,所以现在单例池中还没有对象

1.3 ClassPathBeanDefinitionScanner 扫描

/**
		 * 如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器BeanDefinitionScanner
		 * 专门用来扫描标有@Service,@Component 等等注解的JavaBean,然后通过AnnotatedBeanDefinitionReader来读取信息
		 */
		//todo
		/**
		 * 这里只是创建一个扫描器,主要是扫描@component,注解的类
		 */
		/**
		 * 主要是添加默认的要扫描的标有指定注解的类,@component,和 @javax.annotation.ManagedBean(JSR-250)
		 * @javax.inject.Named(JSR-330),当然@service都是继承@component注解,所以不需要加@service等等
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	

是扫描@component,注解的类
/
/
*
* 主要是添加默认的要扫描的标有指定注解的类,@component,和 @javax.annotation.ManagedBean(JSR-250)
* @javax.inject.Named(JSR-330),当然@service都是继承@component注解,所以不需要加@service等等
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);


这一步其实没什么只是创建一个bean扫描器,扫描指定注解的类

主要需要扫描 三个注解,@component

,@javax.inject.Named,@javax.annotation.ManagedBean

主要是向org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#includeFilters这个集合中添加这三个注解的Class,供后面解析扫描,然后放到spring容器中,**当然自己也可以自定义注解,然后放到这个集合中**
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 1.3.1依赖注入 1.3.2di应用 1.3.3企业级应用中的依赖注入 1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数注入 2.3注入bean属性 2.3.1注入简单的数值 2.3.2使用其他的bean 2.3.3装配集合 2.3.4装配空值 2.4自动装配 2.4.1四种自动装配类型 2.4.2混合使用自动和手动装配 2.4.3何时采用自动装配 2.5控制bean创建 2.5.1bean范围化 2.5.2利用工厂方法来创建bean 2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2spring对aop的支持 4.2创建典型的spring切面 4.2.1创建通知 4.2.2定义切点和通知者 4.2.3使用proxyfactorybean 4.3自动代理 4.3.1为spring切面创建自动代理 4.3.2自动代理@aspectj切面 4.4定义纯粹的pojo切面 4.5注入aspectj切面 4.6小结 第二部分企业spring 第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据源 5.2.1使用jndi数据源 5.2.2使用数据源连接池 5.2.3基于jdbc驱动的数据源 5.3在spring里使用jdbc 5.3.1处理失控的jdbc代码 5.3.2使用jdbc模板 5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api 5.5.1使用jpa模板 5.5.2创建一个实体管理器工厂 5.5.3建立使用jpa的dao 5.6spring和ibatis 5.6.1配置ibatis客户模板 5.6.2建立基于ibatis的dao 5.7缓存 5.7.1配置缓存方案 5.7.2缓存的代理bean 5.7.3注解驱动的缓存 5.8小结 第6章事务管理 6.1理解事务 6.1.1仅用4个词解释事务 6.1.2理解spring对事务管理的支持 6.2选择事务管理器 6.2.1jdbc事务 6.2.2hibernate事务 6.2.3jpa事务 6.2.4jdo事务 6.2.5jta事务 6.3在spring中编写事务 6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理投票弃权 7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BLUE_SEVEN

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

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

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

打赏作者

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

抵扣说明:

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

余额充值