Package org.jtester.module.core.helper

Source Code of org.jtester.module.core.helper.SpringModuleHelper

package org.jtester.module.core.helper;

import java.util.Arrays;

import org.jtester.annotations.SpringApplicationContext;
import org.jtester.core.TestedObject;
import org.jtester.exception.JTesterException;
import org.jtester.module.core.SpringModule;
import org.jtester.module.spring.ApplicationContextFactory;
import org.jtester.module.spring.JTesterBeanFactory;
import org.jtester.module.spring.JTesterSpringContext;
import org.jtester.utility.AnnotationUtils;
import org.jtester.utility.JTesterLogger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;

public class SpringModuleHelper {

  /**
   * 获得当前测试类spring容器中名称为beanname的spring bean
   *
   * @param beanName
   * @return
   */
  public static Object getBeanByName(String beanname) {
    BeanFactory factory = (BeanFactory) TestedObject.getSpringBeanFactory();
    if (factory == null) {
      throw new RuntimeException("can't find SpringApplicationContext for tested class:"
          + TestedObject.currTestedClazzName());
    } else {
      Object bean = factory.getBean(beanname);
      return bean;
    }
  }

  /**
   * 强制重新加载spring 容器<br>
   * Forces the reloading of the application context the next time that it is
   * requested. If classes are given only contexts that are linked to those
   * classes will be reset. If no classes are given, all cached contexts will
   * be reset.
   *
   * @param classes
   *            The classes for which to reset the contexts
   */
  public static void invalidateApplicationContext() {
    boolean springModuleEnabled = ModulesManager.isModuleEnabled(SpringModule.class);
    if (springModuleEnabled) {
      SpringModule module = ModulesManager.getModuleInstance(SpringModule.class);
      module.invalidateApplicationContext();
    }
  }

  /**
   * 初始化当前测试类用到的spring application context对象
   *
   * @param testedObject
   * @param contextFactory
   * @return does initial spring context successfully
   */
  @SuppressWarnings("rawtypes")
  public static JTesterBeanFactory initSpringContext(Class testClazz, ApplicationContextFactory contextFactory) {
    JTesterBeanFactory beanFactory = (JTesterBeanFactory) TestedObject.getSpringBeanFactory();
    if (beanFactory != null) {
      return beanFactory;
    }
    SpringApplicationContext annotation = AnnotationUtils.getClassLevelAnnotation(SpringApplicationContext.class,
        testClazz);
    if (annotation == null) {
      return null;
    }

    long startTime = System.currentTimeMillis();

    String[] locations = annotation.value();
    boolean ignoreNoSuchBean = annotation.ignoreNoSuchBean();
    JTesterSpringContext context = contextFactory.createApplicationContext(Arrays.asList(locations),
        ignoreNoSuchBean);

    context.refresh();
    long duration = System.currentTimeMillis() - startTime;
    JTesterLogger.warn(String.format("take %d ms to init spring context for test obejct[%s]", duration,
        testClazz.getName()));

    beanFactory = context.getJTesterBeanFactory();
    TestedObject.setSpringContext(beanFactory);
    return beanFactory;
  }

  /**
   * 释放测试类的spring容器
   *
   * @param springContext
   *            AbstractApplicationContext实例,这里定义为Object是方便其它模块脱离spring依赖
   */
  public static void closeSpringContext(Object beanFactory) {
    if (beanFactory == null) {
      return;
    }
    if (beanFactory instanceof JTesterBeanFactory) {
      ((JTesterBeanFactory) beanFactory).destroySingletons();
      JTesterLogger.warn("close spring context for class:" + TestedObject.currTestedClazzName());
    } else {
      String error = String.format("there must be something error, the type[%s] object isn't a spring context.",
          beanFactory.getClass().getName());
      throw new RuntimeException(error);
    }
  }

  /**
   * 增加自动跟踪的auto tracer bean definition
   *
   * @param beanFactory
   */
  public static void addTracerBeanDefinition(final BeanDefinitionRegistry beanFactory) {
    AbstractBeanDefinition pointcut = new GenericBeanDefinition();
    pointcut.setBeanClassName(org.jtester.module.tracer.spring.TracerMethodRegexPointcut.class.getName());
    pointcut.setScope("singleton");
    pointcut.setAutowireCandidate(false);

    pointcut.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);

    beanFactory.registerBeanDefinition("jtester-internal-methodname-pointcut", pointcut);

    AbstractBeanDefinition advice = new GenericBeanDefinition();
    advice.setBeanClassName(org.jtester.module.tracer.spring.SpringBeanTracer.class.getName());
    advice.setScope("singleton");
    advice.setAutowireCandidate(false);

    advice.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);

    beanFactory.registerBeanDefinition("jtester-internal-springbeantracer", advice);

    AbstractBeanDefinition advisor = new GenericBeanDefinition();
    advisor.setBeanClassName(org.springframework.aop.support.DefaultPointcutAdvisor.class.getName());
    advisor.setScope("singleton");
    advisor.setAutowireCandidate(false);

    advisor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
    advisor.getPropertyValues().addPropertyValue("pointcut",
        new RuntimeBeanReference("jtester-internal-methodname-pointcut"));
    advisor.getPropertyValues().addPropertyValue("advice",
        new RuntimeBeanReference("jtester-internal-springbeantracer"));

    beanFactory.registerBeanDefinition("jtester-internal-beantracer-advisor", advisor);
  }

  /**
   * 返回spring代理的目标对象
   *
   * @param target
   * @return
   */
  public static Object getAdvisedObject(Object target) {
    if (target instanceof org.springframework.aop.framework.Advised) {
      try {
        return ((org.springframework.aop.framework.Advised) target).getTargetSource().getTarget();
      } catch (Exception e) {
        throw new JTesterException(e);
      }
    } else {
      return target;
    }
  }
}
TOP

Related Classes of org.jtester.module.core.helper.SpringModuleHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.