All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jianggujin.modulelink.impl.spring.JSpringModule Maven / Gradle / Ivy

/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * 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.jianggujin.modulelink.impl.spring;

import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.LogFactory;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.context.ConfigurableApplicationContext;

import com.jianggujin.modulelink.JAction;
import com.jianggujin.modulelink.JModuleConfig;
import com.jianggujin.modulelink.JModuleLinkException;
import com.jianggujin.modulelink.impl.JAbstractModule;
import com.jianggujin.modulelink.util.JAssert;
import com.jianggujin.modulelink.util.JLogFactory;
import com.jianggujin.modulelink.util.JLogFactory.JLog;
import com.jianggujin.modulelink.util.JStringUtils;

/**
 * 集成Spring上下文的模块,从Spring上下中找Action
 * 
 * @author jianggujin
 *
 */
public class JSpringModule extends JAbstractModule {

   private static final JLog logger = JLogFactory.getLog(JSpringModule.class);

   private final ConfigurableApplicationContext applicationContext;

   public JSpringModule(JModuleConfig moduleConfig, ConfigurableApplicationContext applicationContext)
         throws ClassNotFoundException, InstantiationException, IllegalAccessException {
      super(moduleConfig);
      this.applicationContext = applicationContext;
      Set actions = moduleConfig.getActions();
      Set exclusionActions = moduleConfig.getExclusionActions();
      Set loadedActions = new HashSet();
      applicationContext.getBeanFactory();
      // 查找Action
      for (JAction action : applicationContext.getBeansOfType(JAction.class).values()) {
         String className = action.getClass().getName();
         if (exclusionActions.contains(className))
            continue;
         String actionName = action.getActionName();
         if (JStringUtils.isBlank(actionName)) {
            throw new JModuleLinkException("JModuleLink scan actions actionName is null");
         }
         JAssert.checkState(!this.actions.containsKey(actionName), "duplicated action %s found by: %s",
               JAction.class.getSimpleName(), actionName);
         if (logger.isInfoEnabled()) {
            logger.info("JModuleLink scan action: " + actionName + ": bean: " + action);
         }
         if (this.defaultAction == null && action.isDefault(moduleConfig.getName())) {
            this.defaultAction = action;
         }
         loadedActions.add(className);
         this.actions.put(actionName, action);
      }
      if (logger.isInfoEnabled()) {
         logger.info("JModuleLink scan actions finish: " + this.actions);
      }
      loadedActions.addAll(exclusionActions);
      if (!actions.isEmpty()) {
         for (String action : actions) {
            if (loadedActions.contains(action))
               continue;
            Class clazz = this.applicationContext.getClassLoader().loadClass(action);
            if (clazz.isInterface() || !JAction.class.isAssignableFrom(clazz)
                  || Modifier.isAbstract(clazz.getModifiers())) {
               continue;
            }
            JAction ins = (JAction) clazz.newInstance();
            String actionName = ins.getActionName();
            if (JStringUtils.isBlank(actionName)) {
               throw new JModuleLinkException("JModuleLink load action actionName must not be null");
            }
            JAssert.checkState(!this.actions.containsKey(actionName), "duplicated action %s found by: %s",
                  JAction.class.getSimpleName(), actionName);
            if (logger.isInfoEnabled()) {
               logger.info("JModuleLink load action: " + actionName + ", bean: " + ins);
            }
            if (this.defaultAction == null && ins.isDefault(moduleConfig.getName())) {
               this.defaultAction = ins;
            }
            this.actions.put(actionName, ins);
         }
      }
      if (logger.isInfoEnabled()) {
         logger.info("JModuleLink load actions finish: " + this.actions);
      }
   }

   @Override
   public void destroy() {
      super.destroy();
      if (logger.isInfoEnabled()) {
         logger.info("close application context: " + applicationContext);
      }
      // 关闭spring上下文
      closeQuietly(applicationContext);
      // 清除类加载器
      clear(applicationContext.getClassLoader());
   }

   /**
    * 清除类加载器
    *
    * @param classLoader
    */
   private static void clear(ClassLoader classLoader) {
      JAssert.checkNotNull(classLoader, "classLoader must not be null.");
      // 清除指定加载器的introspection cache
      CachedIntrospectionResults.clearClassLoader(classLoader);
      LogFactory.release(classLoader);
   }

   /**
    * 关闭Spring上下文
    * 
    * @param applicationContext
    */
   private static void closeQuietly(ConfigurableApplicationContext applicationContext) {
      if (applicationContext == null) {
         throw new NullPointerException("applicationContext is null");
      }
      try {
         applicationContext.close();
      } catch (Exception e) {
         logger.error("failed to close application context", e);
      }
   }

   @Override
   public ClassLoader getModuleClassLoader() {
      return this.applicationContext.getClassLoader();
   }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy