解析FactoryBean

请到个人博客网站,查看原文

BeanFactory

是访问bean container的基本接口.

BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

FactoryBean

If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

FactoryBean以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

DefaultListableBeanFactory

AbstractRefreshableApplicationContext为什么持有DefaultListableBeanFactory
BeanFactory的接口其实是由这个DefaultListableBeanFactory代理实现的。
比如:

	@Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}

其中getBeanFactory()是由AbstractRefreshableApplicationContext

	@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		DefaultListableBeanFactory beanFactory = this.beanFactory;
		if (beanFactory == null) {
			throw new IllegalStateException("BeanFactory not initialized or already closed - " +
					"call 'refresh' before accessing beans via the ApplicationContext");
		}
		return beanFactory;
	}

依赖查找

  1. 单一类型依赖查找
  2. 集合类型
  3. 层次类型
  4. 延时
  5. 安全
  6. 内建可查找
  7. 依赖查找中的经典异常

依赖注入

xml,annotation,api三种方式

  1. setter注入方式
  2. constructor注入方式
  3. field注入
    @autowired注解,不能注入静态字段static
  4. 方法注入method
  5. 接口回调注入Aware接口

@Autowired注入原理

  1. bean的设置属性

    AbstractAutowiredCapableBeanFactory#populateBean()

    for (BeanPostProcessor bp : getBeanPostProcessors()) {
    			if (bp instanceof InstantiationAwareBeanPostProcessor) {
    				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    				if (pvsToUse == null) {
    					if (filteredPds == null) {
    						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    					}
    					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    					if (pvsToUse == null) {
    						return;
    					}
    				}
    				pvs = pvsToUse;
    			}
    		}
    

    处理bean的设置属性的前置和后置方法(InstantiationAwareBeanPostProcessor),其中@Autowired就是实现postProcessProperties()这个后置方法

  2. AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法

     @Override
     public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
     	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
     	try {
     		metadata.inject(bean, beanName, pvs);
     	}
     	catch (BeanCreationException ex) {
     		throw ex;
     	}
     	catch (Throwable ex) {
     		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
     	}
     	return pvs;
     }
    

inject()

@Override
  	protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
  		Field field = (Field) this.member;
  		Object value;
  		if (this.cached) {
  			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
  		}
  		else {
  			DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
  			desc.setContainingClass(bean.getClass());
  			Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
  			Assert.state(beanFactory != null, "No BeanFactory available");
  			TypeConverter typeConverter = beanFactory.getTypeConverter();
  			try {
  				value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
  			}
  			catch (BeansException ex) {
  				throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
  			}
  			synchronized (this) {
  				if (!this.cached) {
  					if (value != null || this.required) {
  						this.cachedFieldValue = desc;
  						registerDependentBeans(beanName, autowiredBeanNames);
  						if (autowiredBeanNames.size() == 1) {
  							String autowiredBeanName = autowiredBeanNames.iterator().next();
  							if (beanFactory.containsBean(autowiredBeanName) &&
  									beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
  								this.cachedFieldValue = new ShortcutDependencyDescriptor(
  										desc, autowiredBeanName, field.getType());
  							}
  						}
  					}
  					else {
  						this.cachedFieldValue = null;
  					}
  					this.cached = true;
  				}
  			}
  		}
  		if (value != null) {
  			ReflectionUtils.makeAccessible(field);
  			field.set(bean, value);
  		}
  	}
  1. 依赖处理
    AutowireCapableBeanFactory#resolveDependency();
    默认实现是DefaultListableBeanFactory

	/**
	 * Resolve the specified dependency against the beans defined in this factory.
	 * @param descriptor the descriptor for the dependency (field/method/constructor)
	 * @param requestingBeanName the name of the bean which declares the given dependency
	 * @param autowiredBeanNames a Set that all names of autowired beans (used for
	 * resolving the given dependency) are supposed to be added to
	 * @param typeConverter the TypeConverter to use for populating arrays and collections
	 * @return the resolved object, or {@code null} if none found
	 * @throws NoSuchBeanDefinitionException if no matching bean was found
	 * @throws NoUniqueBeanDefinitionException if more than one matching bean was found
	 * @throws BeansException if dependency resolution failed for any other reason
	 * @since 2.5
	 * @see DependencyDescriptor
	 */
	@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;

请到个人博客网站,查看原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值