Spring初始化Bean的使用方法
发表于:2024-10-14 作者:千家信息网编辑
千家信息网最后更新 2024年10月14日,本篇内容主要讲解"Spring初始化Bean的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spring初始化Bean的使用方法"吧!1、记录创建
千家信息网最后更新 2024年10月14日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安全错误
数据库的锁怎样保障安全
广工选修网络安全与信息安全
金蝶软件数据库SQL
h5下载数据库
遵化方形互联网科技
战地5那个服务器挂少
endnote导入数据库
网络安全等级保护制度详
ibm服务器黑屏无法开机
想做软件开发要如何选择技术
呼和浩特民族学院网络安全负责人
网络安全产品运营学习
计算机二级网络技术论文
永恒之塔怀旧服人最多的服务器
超哥网络技术传媒
服务器机柜销售公司
服务器证书验证
河南放心软件开发服务品质保障
服务器内存和显卡的区别
靠谱的erp软件开发方案
mek挖矿机服务器
面部捕捉软件开发
网络安全执法视频
网络安全法需绑定手机号
荣耀全明星无法连接服务器
服务器怎么配置raid2.0
社保认证服务器配置如何填写
火车数据库设计怎么答辩
天津特锐科技互联网厂
网络安全受骗
网络安全哪个公司待遇好