/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.springext.support.context; import static java.util.Collections.*; import java.lang.reflect.Field; import java.util.Map; import com.alibaba.citrus.springext.util.ProxyTargetFactory; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * 这个类扩展了<code>DefaultListableBeanFactory</code>,改进了如下问题: * <ul> * <li>子context可继承parent * <code>DefaultListableBeanFactory.resolvableDependencies</code>。 * 例如:在父context中定义的<code><request-contexts /></code> * 将在resolvableDependencies中注册<code>HttpServletRequest</code>等singleton * proxy对象。如果没有这个类,那么在子context中定义的bean,将不能注入这些对象。</li> * <li>子context不能覆盖父context中已有的实现了<code>ProxyTargetFactory</code> * 接口的resolvableDependencies对象。否则, * WebApplicationContext会自动注册非singleton的request对象 * ,使得子context不能取得父context中注册的singleton proxy。</li> * <li>自动合并同名的bean definitions,以实现功能:可覆盖bean的默认配置。</li> * </ul> * * @author Michael Zhou */ class InheritableListableBeanFactory extends DefaultListableBeanFactory { private final Map<Class<?>, Object> parentResolvableDependencies; InheritableListableBeanFactory(BeanFactory parentBeanFactory) { super(parentBeanFactory); Map<Class<?>, Object> resolvableDependencies = getResolvableDependencies(this); Map<Class<?>, Object> parentResolvableDependencies = getResolvableDependencies(parentBeanFactory); if (parentResolvableDependencies != null) { if (resolvableDependencies != null) { resolvableDependencies.putAll(parentResolvableDependencies); } this.parentResolvableDependencies = unmodifiableMap(parentResolvableDependencies); } else { this.parentResolvableDependencies = null; } } @SuppressWarnings("unchecked") private Map<Class<?>, Object> getResolvableDependencies(BeanFactory parentBeanFactory) { if (parentBeanFactory instanceof DefaultListableBeanFactory) { try { Field field = DefaultListableBeanFactory.class.getDeclaredField("resolvableDependencies"); field.setAccessible(true); return (Map<Class<?>, Object>) field.get(parentBeanFactory); } catch (Exception e) { logger.warn("Failed to get value of DefaultListableBeanFactory.resolvableDependencies, " + "autowiring of singleton proxy may function wrong", e); } } return null; } /** 避免重复注册parent中已有的对象,但可以覆盖当前context中的对象。 */ @Override @SuppressWarnings("rawtypes") public void registerResolvableDependency(Class dependencyType, Object autowiredValue) { if (parentResolvableDependencies == null || !(parentResolvableDependencies.get(dependencyType) instanceof ProxyTargetFactory)) { super.registerResolvableDependency(dependencyType, autowiredValue); } } @Override public void registerBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { BeanDefinition existingBd; // 尝试查找当前的bean是否已经注册过 try { existingBd = this.getBeanDefinition(beanName); } catch (NoSuchBeanDefinitionException e) { existingBd = null; } // 如果当前的bean已经被定义,使用当前的新配置来覆盖原始的定义 if (existingBd != null && existingBd instanceof AbstractBeanDefinition) { ((AbstractBeanDefinition) existingBd).overrideFrom(bd); super.registerBeanDefinition(beanName, existingBd); } else { super.registerBeanDefinition(beanName, bd); } } }