Java之工厂模式理解

一、前言

接触过java程序的小伙伴们,应该在相关应用日志里经常看到“xxxxFactory”的字眼,比如下面的报错,那这些factory是什么,又该怎样理解呢?这里咱们从非程序员来了解下Factory下的神秘面纱。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.interceptor.CacheInterceptor#0'
: Cannot resolve reference to bean 'cacheManager' while setting bean property 'cacheManager';
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' available

二、spring Factory

Spring是java应用程序最常用的轻量级开发框架了,Spring的核心就是提供了一个IoC(Inversion of Control,控制反转,也就是反射,Java的反射是指程序在运行期可以拿到一个对象的所有信息;IoC通过依赖注入(DI)方式实现对象之间的松耦合关系,因此它也称依赖注入)容器,它可以管理所有轻量级的JavaBean组件,提供的底层服务包括组件的生命周期管理、配置和组装服务、AOP支持,以及建立在AOP基础上的声明式事务服务等。简单说,IOC容器就是由spring用来负责控制对象的生命周期和对象间关系的,是一个对象定义其依赖关系而不创建它们的过程。Spring提供了IOC容器的两种实现方式:

BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身的,不是提供给开发人员使用的。

② ApplicationContext:BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory。

Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。更多参看Java教程;在 Spring 中,构成应用程序主干(即应用程序由一个个bean构成的)并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象。Factory bean跟普通bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂bean的getObject方法所返回的对象。工厂bean必须实现org.springframework.beans.factory.FactoryBean接口。综上,bean它是一个Java对象,是根据bean规范编写出来的类,并由bean容器生成的,这个对象就是一个bean。这样的话,java对象(实例化的bean)就可以被spring ioc容器(又称bean容器)来管理使用了。

1)Spring Bean初始化

在这里插入图片描述
所有spring bean 初始化都是由AbstractBeanFactory.doGetBean方法实现的。它先从三级缓存中获取,如果缓存中都没有。再去判断是否存在父容器,从父容器中获取。没有正式就进入bean 初始化流程,先根据beanName 获取到RootBeanDefinition,bean类元信息、先处理dependsOn中bean,保证bean依赖的创建顺序,下一步按照不同scope 进行bean 对象初始化

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
    
    
        //name 前缀处理  beanFactory beanName 带有&开头
		String beanName = transformedBeanName(name);
		Object beanInstance;
        //从三级缓存去取bean,三级中都没有则返回null,说明对象还没有创建
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
    
     //如果缓存中bean 是FactoryBean实例,要通过接口获取到实际bean
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
    
     
             //判断bean对象标记是否正在创建中,如果正在创建中则不应该继续下去,出现依赖循环就会出现这个错误
			if (isPrototypeCurrentlyInCreation(beanName)) {
    
    
				throw new BeanCurrentlyInCreationException(beanName);
			}
			BeanFactory parentBeanFactory = getParentBeanFactory();
            // 检查父容器是否存在,尝试从父容器中获取
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    
    
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
    
    
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
    
    
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
    
    
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
    
    
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
    
     //缓存中标记beanName 正在被创建
				markBeanAsCreated(beanName);
			}
			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
    
    
				if (requiredType != null) {
    
    
					beanCreation.tag("beanType", requiredType::toString);
				}
				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) {
    
      //bean 中@DependsOn 信息,用于标记bean之间初始化顺序,优先创建@DependsOn   中bean
					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);
						try {
    
    
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
    
    
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

			     //创建单例对象
				if (mbd.isSingleton()) {
    
     //重点就在这里实例化对象  ,getSingleton 就是在这里将创建完成对象加入到一级缓存中
					sharedInstance = getSingleton(beanName, () -> {
    
    
						try {
    
    
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) 
							destroySingleton(beanName);
							throw ex;
						}
					});
                    //如果生成bean 是FactoryBean ,再获取真正的对象
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                //作用域 = prototype,因为不会放入缓存中,每次获取都要重新创建
				else if (mbd.isPrototype()) {
    
    
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
    
    
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
    
    
						afterPrototypeCreation(beanName);
					}
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
    
     // session request 这些作用域,由作用域容器去管理这些对象
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
    
    
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
    
    
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
    
    
						Object scopedInstance = scope.get(beanName, () -> {
    
    
							beforePrototypeCreation(beanName);
							try {
    
    
								return createBean(beanName, mbd, args);
							}
							finally {
    
    
								afterPrototypeCreation(beanName);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
    
    
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
    
    
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
    
    
				beanCreation.end();
			}
		}
                //返回初始化成功的对象,一个对象初始化就这样完成的了  
		return adaptBeanInstance(name, beanInstance, requiredType);  
	}

注意:bean创建都是伴随着三级缓存之间的转换完成的,对象不同状态分别存在不同缓存中;主要作用就是创建对象ObjectFactory首先放入三级换缓存(装载创建bean的工厂对象)中,当调用getObject 创建实例时,会将创建好对象加入二级缓存( 过早暴露单例对象,此时bean刚刚完成初始化,未完成属性注入和执行 init 方法)中,并且删除三级中缓存,当对象已经完成初始化方法和属性注入,再将缓存添加到一级缓存(用于存放完全可以使用单例bean,也就是初始化完成并且注入所有依赖)中,并且删除二级缓存。

猜你喜欢

转载自blog.csdn.net/ximenjianxue/article/details/127493672