Spring初始化Bean的使用方法
发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,本篇内容主要讲解"Spring初始化Bean的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring初始化Bean的使用方法"吧!1、记录创建
千家信息网最后更新 2025年01月31日Spring初始化Bean的使用方法
本篇内容主要讲解"Spring初始化Bean的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring初始化Bean的使用方法"吧!
1、记录创建bean的ObjectFactory,目的是为了解决循环依赖
if (instanceWrapper == null) { //上一篇bean的加载后部分主要分析了bean的创建,此步骤完成之后bean已经创建完成,但属性还没有赋值,Spring //解决循环依赖的关键步骤就在此步骤完成之后,bean已创建但还没有属性赋值,如下图 instanceWrapper = createBeanInstance(beanName, mbd, args);}
如下图,以最简单的AB循环依赖为例,A中有属性类B,B中又有属性类A,那么初始化beanA的过程如下图.
//上图中addSingletonFactory逻辑,只有是单例的,允许循环依赖且该bean正在创建中(创建时会记录该属性,创建完成会移除该属性),//只有三个条件都满足才会addSingletonFactoryboolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) { //为避免后期循环依赖,可以在bean初始化后属性赋值之前将创建实例的ObjectFactory加入工厂 addSingletonFactory(beanName, new ObjectFactory
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { //放入map中 this.singletonFactories.put(beanName, singletonFactory); //目的是检测循环引用,移除 this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }}
//我们熟知的AOP就是在这里将advice动态织如bean中,若没有则直接返回beanprotected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); if (exposedObject == null) { return exposedObject; } } } } return exposedObject;}
2、属性注入
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { //1.创建bean,但还没有属性赋值 instanceWrapper = createBeanInstance(beanName, mbd, args); } //2.条件满足的话讲ObjectFactory放入map中,为了解决循环依赖 addSingletonFactory(beanName, new ObjectFactory
//之前已经分析了步骤1创建bean和步骤2添加ObjectFactory,现在来分析属性赋值populateBean。protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { //读取配置文件,解析标签之后,此处的pvs已经有值了,就是配置文件中配置的lwh sayHello PropertyValues pvs = mbd.getPropertyValues(); if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //根据名称自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } //根据类型自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //属性赋值 applyPropertyValues(beanName, mbd, bw, pvs);}
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //寻找bw中需要依赖注入的属性,若是配置文件中配置了person属性,则此处查出来的propertyNames为空 //因为配置文件中配置了name为person的bean,此处查找出来的propertyNames封装的就是person,若是将配置文 //件中autowire改为byType程序也可以正常运行;若将配置的person的id改为其他的,则byName不能正常运行,而 //byType可以正常运行 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { if (containsBean(propertyName)) { //递归初始化相关的bean,此处为person Object bean = getBean(propertyName); //加到pvs属性中 pvs.add(propertyName, bean); registerDependentBean(propertyName, beanName); } }}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { MutablePropertyValues mpvs = null; Listoriginal; if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; if (mpvs.isConverted()) { try { bw.setPropertyValues(mpvs); return; } } original = mpvs.getPropertyValueList(); } else { original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); List deepCopy = new ArrayList (original.size()); boolean resolveNecessary = false; for (PropertyValue pv : original) { if (pv.isConverted()) { deepCopy.add(pv); } else { String propertyName = pv.getName(); Object originalValue = pv.getValue(); Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } try { //赋值核心代码,此步骤完成之后,bean中的属性就被赋值了 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); }}
3、调用一系列初始化方法
//分析完了属性赋值populateBean方法,然后分析一系列初始化方法//属性赋值populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) { //调用初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd);}protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { //1.激活Aware方法 invokeAwareMethods(beanName, bean); Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //2.执行BeanPostProcessor的before方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //3.激活用户定义的初始化方法,包括接口InitializingBean中的初始化方法和用户配置的init-method invokeInitMethods(beanName, wrappedBean, mbd); } if (mbd == null || !mbd.isSynthetic()) { //4.执行BeanPostProcessor的after方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}
步骤1:激活Aware方法
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { //附录1中的类实现了BeanFactoryAware接口,因此会调用该方法,输出注入容器BeanFactroy ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } }}
步骤2:执行BeanPostProcessor的before方法
ConfigurableBeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));//BeanFactory要手动注册BeanPostProcessor,而ApplicationContext会手动检测bf.addBeanPostProcessor(new MyTestBean());bf.getBean("myTestBean", MyTestBean.class);
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){ Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //调用这边会输出我是MyTestBean的postProcessBeforeInitialization方法 result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result;}
步骤3:激活用户的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd){ boolean isInitializingBean = (bean instanceof InitializingBean); //删去了部分代码 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { //调用InitializingBean接口中定义的初始化方法 ((InitializingBean) bean).afterPropertiesSet(); } if (mbd != null) { //配置文件init-method中配置的初始化方法 String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //底层使用反射调用初始化方法 invokeCustomInitMethod(beanName, bean, mbd); } }}
步骤4:执行BeanPostProcessor的after方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName){ Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result;}
附录1、根据名称注入例子
public class MyTestBean implements BeanFactoryAware, BeanPostProcessor, InitializingBean, DestructionAwareBeanPostProcessor{ private BeanFactory beanFactory; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } private String testStr = "xbx"; public String getTestStr() { return testStr; } public void setTestStr(String testStr) { this.testStr = testStr; } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("注入容器BeanFactory"); this.beanFactory = beanFactory; } public void init(){ System.out.println("我是MyTestBean的初始化方法"); } public void destroy(){ System.out.println("我是MyTestBean的销毁方法"); } public Object postProcessBeforeInitialization(Object bean, String beanName){ System.out.println("我是MyTestBean的postProcessBeforeInitialization方法"); return null; } public Object postProcessAfterInitialization(Object bean, String beanName){ System.out.println("我是MyTestBean的postProcessAfterInitialization方法"); return null; } public void afterPropertiesSet() throws Exception { System.out.println("我是MyTestBean的自定义的初始化方法"); } public void postProcessBeforeDestruction(Object bean, String beanName){ System.out.println("我是MyTestBean的自定义的销毁方法"); }}
//配置文件中只配置了testStr属性,并没有配置person属性
到此,相信大家对"Spring初始化Bean的使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
方法
属性
配置
步骤
循环
文件
分析
激活
使用方法
就是
接口
用户
运行
代码
内容
只有
名称
容器
手动
条件
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
防溺水 网络安全教育
没有系统的服务器怎么安装虚拟机
武汉电脑软件开发团队
软件开发排计划软件
机关单位网络安全宣传周活动计划
数据库 int 11
近距离无线通信的网络安全
小学三年级网络安全黑板报
微软软件开发工具
在中央网络安全和信息化网络小组
网络技术基础考试答案配伍题
网络技术的增值税率
无线网络技术口碑推荐
网络安全管理局 张新
江门市天蝎软件开发有限公司
visio画数据库
首个网络安全满意度报告
网络安全每日一讲
关于网络安全产品的营销策略
崇明区智能化软件开发销售方法
网络安全宣传周 主题
激活工具服务器不能用
笔记本电脑服务器断开
防诈骗网络安全知识教育内容
如何判断服务器ip
工控组态技术实时数据库
软件开发的职位
广电网络安全机房规范化建设
通过数据库查询健康码存在异常
杭州软件开发定制哪家服务好