当前位置: 首页 > news >正文

怎么做自己的导航网站/徐州网站设计

怎么做自己的导航网站,徐州网站设计,wordpress category隐藏,注册一个平台需要多少钱在【spring 源码】IOC 之 ClassPathXmlApplicationContext 1-5 小段源码里多次调用了getBean()的方法,我们经常通过这个方法从beanFactory里获取bean实例,而bean的初始化细节也在这个方法里实现了。本文重点解析getBean&#xff0…

在【spring 源码】IOC 之 ClassPathXmlApplicationContext 1-5 小段源码里多次调用了getBean()的方法,我们经常通过这个方法从beanFactory里获取bean实例,而bean的初始化细节也在这个方法里实现了。本文重点解析getBean()方法。

AbstractBeanFactory#getBean()

	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}// L235@SuppressWarnings("unchecked")protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 从手动注册的单例缓存里取出相关实例在下面的1-0展开细说Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {//创建实例的第一种方式:正在创建的共享单例实例不为空且是无参数的情况(此时的单例对象并没有真正实例化完毕,仅仅是提前曝光,解决循环依赖的策略)...//打印相关日志,略// 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance,// 如果是 FactoryBean 的话,返回它创建的那个实例对象 详见1-1bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {//创建实例的第二种方式// 当前线程已经创建过了此 beanName 的 prototype 类型的 bean,那么抛异常.能调用到这里的肯定都是单例的if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// 检查当前父bean工厂是否存在该bean实例,如果不存在就递归调用知道有实例返回String nameToLookup = originalBeanName(name);if (args != null) {// 有参数,这里不展开详说return (T) parentBeanFactory.getBean(nameToLookup, args);}else {// 无参数创建实例return parentBeanFactory.getBean(nameToLookup, requiredType);}}if (!typeCheckOnly) {//将beanName放入alreadyCreated,标识其实例已经创建markBeanAsCreated(beanName);}try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);getBean(dep);}}// Create bean instance.if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {//这里是第二种创建bean实例的方式,1-2展开详说return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//非单例情况,忽略else if (mbd.isPrototype()) {...}else {...}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// Check if required type matches the type of the actual bean instance.if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {try {return getTypeConverter().convertIfNecessary(bean, requiredType);}catch (TypeMismatchException ex) {...}}return (T) bean;}
复制代码

1-0 getSingleton(beanName);

这里的getSingleton()调用了AbstractBeanFactory父类DefaultSingletonBeanRegistry#getSingleton()方法。

在此之前我们先了解一下spring单例的三级缓存

/** 已实例好单例对象缓存 为了方便理解称为一级缓存(下同)*/
private final Map singletonObjects = new ConcurrentHashMap(256);
/** 提前曝光的单例对象缓存(尚未实例完) 二级缓存*/
private final Map earlySingletonObjects = new HashMap(16);
/** 单例对象工厂缓存 三级缓存*/
private final Map> singletonFactories = new HashMap>(16);复制代码

DefaultSingletonBeanRegistry.java L172

public Object getSingleton(String beanName) {return getSingleton(beanName, true);
}
/*** Return the (raw) singleton object registered under the given name.* Checks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* 大体意思是:返回一个以给定名称注册的单例对象,检查已经实例好的单例池子,同时也允许对当前对象的引用*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {//单例对象的cacheObject singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//一级缓存里没有该对象并且此beanName正在创建过程中才会进来,因为正在创建的bean也许会在二级缓存里synchronized (this.singletonObjects) {//二级缓存中取singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {//如果二级缓存里没有就从三级缓存里取ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {//三级缓存里不为空就将其放入二级缓存里,并将其从三级缓存里移除singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
复制代码

到这里已经把spring 单例的三级缓存说完了,这三个缓存是spring处理循环依赖的重要依据,有兴趣的话可以看我之前的文章《spring是如何解决循环依赖的?》。

1-1 getObjectForBeanInstance(sharedInstance, name, beanName, null)第一种创建bean实例的方式

AbstractBeanFactory#getObjectForBeanInstance() L1607

/*** Get the object for the given bean instance, either the bean* instance itself or its created object in case of a FactoryBean.* 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance,* 如果是 FactoryBean 的话,返回它创建的那个实例对象*/
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.//如果这个bean不是工厂bean,直接抛异常,不让其调用者撤销引用工厂if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {//name以&开头并且bean实例不属于工厂bean,直接抛异常throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, //unless the caller actually wants a reference to the factory.if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {//①如果bean实例不是工厂bean,名称是以&开头,直接放回bean实例//②如果bean实例是工厂bean,名称不是以&开头,直接放回bean实例return beanInstance;}Object object = null;if (mbd == null) {//从factoryBeanObjectCache缓存里取object = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;if (mbd == null && containsBeanDefinition(beanName)) {//将该类的子类、父类配置信息都集中到rootBeanDefinition里mbd = getMergedLocalBeanDefinition(beanName);}boolean synthetic = (mbd != null && mbd.isSynthetic());//下面调用了FactoryBeanRegistrySupport类的getObjectFromFactoryBean(),是从factoryBean里获取bean实例的入口object = getObjectFromFactoryBean(factory, beanName,!synthetic);}return object;
}
复制代码

1-1-0 getObjectFromFactoryBean(factory, beanName,!synthetic)

FactoryBeanRegistrySupport#getObjectFromFactoryBean() L98

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {if (factory.isSingleton() && containsSingleton(beanName)) {//单例场景synchronized (getSingletonMutex()) {Object object = this.factoryBeanObjectCache.get(beanName);if (object == null) {//这里是实例化bean的最核心入口object = doGetObjectFromFactoryBean(factory, beanName);// Only post-process and store if not put there already during getObject() call above// (e.g. because of circular reference processing triggered by custom getBean calls)Object alreadyThere = this.factoryBeanObjectCache.get(beanName);if (alreadyThere != null) {object = alreadyThere;}else {if (object != null && shouldPostProcess) {try {//这里会调用所有BeanPostProcessor#postProcessAfterInitialization的实现方法,这里不做展开,后续会有文章介绍object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName,"Post-processing of FactoryBean's singleton object failed", ex);}}this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));}}return (object != NULL_OBJECT ? object : null);}}else {//非单例场景,这里不做展开...return object;}
}
复制代码
1-1-0-0. ==doGetObjectFromFactoryBean(factory, beanName)==

FactoryBeanRegistrySupport#doGetObjectFromFactoryBean() L148

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)throws BeanCreationException {Object object;try {//调用java的安全模型来实例化相关类,保证安全if (System.getSecurityManager() != null) {AccessControlContext acc = getAccessControlContext();try {object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {return factory.getObject();}}, acc);}catch (PrivilegedActionException pae) {throw pae.getException();}}else {object = factory.getObject();}}catch (FactoryBeanNotInitializedException ex) {throw new BeanCurrentlyInCreationException(beanName, ex.toString());}catch (Throwable ex) {throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);}// Do not accept a null value for a FactoryBean that's not fully// initialized yet: Many FactoryBeans just return null then.if (object == null && isSingletonCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");}return object;}
复制代码

这里只简单说一下,后面会有专门一篇文章详细介绍java的安全模型,感兴趣的同学可以先参考《Java 授权内幕》,Java 安全模型介绍》,《Java安全——安全管理器、访问控制器和类装载器》先了解一下java的安全模型。

小结一下,到这里整个1-1第一种创建bean实例的方法结束了,接下来继续回到AbstractBeanFactory#doGetBean()方法继续往下看。

1-2 createBean(beanName, mbd, args)第二种创建bean方式

//AbstractAutowireCapableBeanFactory#createBean() L447

/*** Central method of this class: creates a bean instance,* populates the bean instance, applies post-processors, etc.* @see #doCreateBean*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {...RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {...}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {...}Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {...}return beanInstance;
}
复制代码

转载于:https://juejin.im/post/5cac584bf265da03a97ac9c6

http://www.lbrq.cn/news/932221.html

相关文章:

  • 订餐网站开发流程/湖南靠谱seo优化
  • 专业做网站的公司保定/企业培训课程名称大全
  • 网站认证主体/网络公司网页设计
  • p2p网站建设多少钱/网络营销的真实案例分析
  • 怎么做门户网站设计方案/网站营销推广有哪些
  • 山东省住房城乡建设部网站/怎么建立企业网站
  • 百度收录网站之后又怎么做/潍坊关键词优化平台
  • 网站开发的热门博客/友情链接检索数据分析
  • 用wordpress建公司网站步骤/广告招商
  • 百度给做网站收费多少/今日新闻国际最新消息
  • 上海网站建设微信开发/重庆seo招聘
  • 做网站交易平台挣钱吗/东莞seo托管
  • 阿里云建设网站好不好/软文是什么意思通俗点
  • 管理网站建设/培训机构招生7个方法
  • 安装wordpress没有选择语言/seo推广优化培训
  • html个人网站设计模板/茂名百度seo公司
  • 凡客建站网/免费网站推广网站破解版
  • 代做一个网站多少钱/网络营销专业技能
  • 做网站需要哪些东西/产品推广活动策划方案
  • 国内网站有哪些/seo推广专员
  • 网站动画用什么程序做/舆情监测软件
  • 网站开发概要设计/深圳营销推广公司
  • pc网站怎么做自适应/广东seo推广
  • mooc 网站建设情况/seo是什么姓
  • ps做网站效果图都是按几倍做/个人建网站步骤
  • 网站建设需要什么软件/seo搜索引擎优化课程总结
  • 赣州网站制作找哪家好/网络服务提供者不是网络运营者
  • 有域名了怎么做网站/企业软文范例
  • 怎么做网站详情页/宁波seo在线优化哪家好
  • 宁波网站建设制作订做/常州网站建设
  • 在线免费的AI文本转语音工具TTSMaker介绍
  • 辐射源定位方法简述
  • CSS 工作原理
  • 【Excel】制作双重饼图
  • ConcurrentHashMapRedis实现二级缓存
  • 再谈亚马逊云科技(AWS)上海AI研究院7月22日关闭事件