/* * Copyright 2008-2009 the original author or authors. * * 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 net.hasor.plugins.spring.factory; import net.hasor.core.ApiBinder; import net.hasor.core.AppContext; import net.hasor.core.Hasor; import net.hasor.core.Module; import net.hasor.core.utils.ExceptionUtils; import net.hasor.core.utils.ResourcesUtils; import net.hasor.core.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.PropertyResourceConfigurer; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PropertiesLoaderSupport; import org.springframework.util.SystemPropertyUtils; import org.springframework.web.context.WebApplicationContext; import javax.servlet.ServletContext; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.Properties; /** * * @version : 2016年2月15日 * @author 赵永春(zyc@hasor.net) */ public class SpringFactoryBean implements FactoryBean, InitializingBean, // ApplicationContextAware, Module { // // protected static Logger logger = LoggerFactory.getLogger(Hasor.class); private AppContext appContext; private ApplicationContext applicationContext; private String config; private String refProperties; private ArrayList<Module> modules; // public String getConfig() { return config; } public void setConfig(String config) { this.config = config; } public String getRefProperties() { return refProperties; } public void setRefProperties(String refProperties) { this.refProperties = refProperties; } public ArrayList<Module> getModules() { return modules; } public void setModules(ArrayList<Module> modules) { this.modules = modules; } // // // @Override public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public final Object getObject() throws Exception { if (this.appContext == null) { throw new IllegalStateException("has not been initialized"); } return this.appContext; } @Override public final Class<?> getObjectType() { return AppContext.class; } @Override public final boolean isSingleton() { return true; } @Override public void afterPropertiesSet() throws Exception { ArrayList<Module> moduleList = this.getModules(); String config = this.getConfig(); // - initData if (!StringUtils.isBlank(config)) { config = SystemPropertyUtils.resolvePlaceholders(config); } if (moduleList == null) { moduleList = new ArrayList<Module>(); } // - AppContext moduleList.add(this); Module[] moduleArrays = moduleList.toArray(new Module[moduleList.size()]); Resource resource = null; if (StringUtils.isNotBlank(config)) { resource = this.applicationContext.getResource(config); } // PropertiesLoaderSupport propertiesLoaderSupport = null; if (this.applicationContext.containsBean(this.refProperties)) { Object obj = this.applicationContext.getBean(this.refProperties); if (obj instanceof PropertiesLoaderSupport) { propertiesLoaderSupport = (PropertiesLoaderSupport) obj; } } // this.appContext = createAppContext(this.applicationContext, resource, propertiesLoaderSupport, moduleArrays); } /**用简易的方式创建{@link AppContext}容器。*/ protected AppContext createAppContext(ApplicationContext context, Resource resource, final PropertiesLoaderSupport envProperties, final Module... modules) throws Exception { // // .获取所有 Spring 的属性配置 HashMap<String, String> envMap = new HashMap<String, String>(); if (envProperties == null) { logger.info("not import any environment variables -> refProperties is null"); } else { Properties props = null; try { Method mergeProperties = PropertiesLoaderSupport.class.getDeclaredMethod("mergeProperties"); Method convertProperties = PropertyResourceConfigurer.class.getDeclaredMethod("convertProperties", Properties.class); mergeProperties.setAccessible(true); convertProperties.setAccessible(true); // props = (Properties) mergeProperties.invoke(envProperties); convertProperties.invoke(envProperties, props); } catch (Exception e) { logger.error("import environment variables error -> " + e.getMessage(), e); throw ExceptionUtils.toRuntimeException(e); } // if (props == null) { logger.warn("not import any environment variables -> form Spring mergeProperties is null"); } else { for (String keyStr : props.stringPropertyNames()) { String keyVal = props.getProperty(keyStr); envMap.put(keyStr, keyVal); } } } logger.info("import environment variables ,done. -> import size :" + envMap.size()); // // .测试 Spring 的上下文是否为 WebApplicationContext boolean testSupportWeb = ResourcesUtils.getResourceAsStream("/org/springframework/web/context/WebApplicationContext.class") != null; if (testSupportWeb) { if (context instanceof WebApplicationContext) { testSupportWeb = true; } else { testSupportWeb = false; } } // // .主配置文件 URI mainSettings = (resource == null) ? null : resource.getURI(); ClassLoader loader = context.getClassLoader(); // // .创建Context AppContext appContext = null; if (testSupportWeb) { ServletContext sc = ((WebApplicationContext) context).getServletContext(); appContext = Hasor.create(sc)// .setMainSettings(mainSettings)// .setLoader(loader)// .putAllData(envMap)// .build(modules);// } else { appContext = Hasor.create()// .setMainSettings(mainSettings)// .setLoader(loader)// .putAllData(envMap)// .build(modules);// } logger.info("create AppContext ,mainSettings = {} , modules = {}", mainSettings, modules); return appContext; } @Override public void loadModule(ApiBinder apiBinder) throws Throwable { // } }