/*
* 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 org.springframework.context.annotation.AnnotationConfigUtils.*;
import java.io.IOException;
import java.util.Collection;
import com.alibaba.citrus.springext.ResourceLoadingExtendable;
import com.alibaba.citrus.springext.ResourceLoadingExtender;
import com.alibaba.citrus.springext.support.resolver.XmlBeanDefinitionReaderProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationListener;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
* 从XML配置文件中装配的,用于WEB环境的<code>ApplicationContext</code>实现类,派生于
* {@link org.springframework.web.context.support.XmlWebApplicationContext}
* ,增加了如下特性:
* <ul>
* <li>支持<code>ConfigurationPoint</code>机制。</li>
* <li>扩展的resource loading机制。假如<code>ResourceLoadingExtender</code>
* 被设置,则使用它来装载资源,否则使用默认的装载器。</li>
* <li>默认打开annotation config,相当于<code><context:annotation-config/></code>。
* </li>
* <li>假如<code>parentResolvableDependenciesAccessible==true</code>,则支持从parent
* context中取得预先置入<code>resolvableDependencies</code>中的对象。默认为<code>true</code>。</li>
* </ul>
* <p>
* 建议所有非WEB应用的application context从{@link AbstractXmlApplicationContext}
* 派生;对于简单的情形,如单元测试,直接从子类{@link XmlApplicationContext}中创建实例。
* </p>
*
* @author Michael Zhou
* @see AbstractXmlApplicationContext
* @see XmlApplicationContext
*/
public class XmlWebApplicationContext extends org.springframework.web.context.support.XmlWebApplicationContext
implements ResourceLoadingExtendable {
private ResourceLoadingExtender resourceLoadingExtender;
private boolean parentResolvableDependenciesAccessible = true;
/** 是否可访问到parent context中的resolvableDependencies。 默认是可访问。 */
public boolean isParentResolvableDependenciesAccessible() {
return parentResolvableDependenciesAccessible;
}
public void setParentResolvableDependenciesAccessible(boolean parentResolvableDependenciesAccessible) {
this.parentResolvableDependenciesAccessible = parentResolvableDependenciesAccessible;
}
public void setResourceLoadingExtender(ResourceLoadingExtender resourceLoadingExtender) {
Collection<ApplicationListener> listeners = new GetApplicationListeners(this).invoke();
if (this.resourceLoadingExtender != null) {
listeners.remove(this.resourceLoadingExtender);
}
this.resourceLoadingExtender = resourceLoadingExtender;
if (resourceLoadingExtender instanceof ApplicationListener) {
listeners.add((ApplicationListener) resourceLoadingExtender);
}
}
@Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
new XmlBeanDefinitionReaderProcessor(beanDefinitionReader).addConfigurationPointsSupport();
}
/** 打开annotation注入。 */
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.customizeBeanFactory(beanFactory);
registerAnnotationConfigProcessors(beanFactory, null);
}
@Override
protected DefaultListableBeanFactory createBeanFactory() {
if (isParentResolvableDependenciesAccessible()) {
return new InheritableListableBeanFactory(getInternalParentBeanFactory());
} else {
return super.createBeanFactory();
}
}
/** 扩展<code>ResourceLoader</code>机制,实现自定义的资源装载。 */
@Override
protected Resource getResourceByPath(String path) {
Resource resource = null;
if (resourceLoadingExtender != null) {
resource = resourceLoadingExtender.getResourceByPath(path);
}
if (resource == null) {
resource = super.getResourceByPath(path);
}
return resource;
}
/** 扩展<code>ResourcePatternResolver</code>机制,实现自定义的资源装载。 */
@Override
protected ResourcePatternResolver getResourcePatternResolver() {
final ResourcePatternResolver defaultResolver = super.getResourcePatternResolver();
return new ResourcePatternResolver() {
public Resource[] getResources(String locationPattern) throws IOException {
ResourcePatternResolver resolver = null;
if (resourceLoadingExtender != null) {
resolver = resourceLoadingExtender.getResourcePatternResolver();
}
if (resolver == null) {
resolver = defaultResolver;
}
return resolver.getResources(locationPattern);
}
public ClassLoader getClassLoader() {
return defaultResolver.getClassLoader();
}
public Resource getResource(String location) {
return defaultResolver.getResource(location);
}
};
}
}