Package com.firefly.core

Source Code of com.firefly.core.AbstractApplicationContext

package com.firefly.core;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.firefly.annotation.Component;
import com.firefly.annotation.Controller;
import com.firefly.annotation.Inject;
import com.firefly.annotation.Interceptor;
import com.firefly.core.support.BeanReader;
import com.firefly.core.support.annotation.AnnotationBeanReader;

abstract public class AbstractApplicationContext implements ApplicationContext {

  protected Map<String, Object> map;
  protected BeanReader beanReader;

  @SuppressWarnings("unchecked")
  @Override
  public <T> T getBean(Class<T> clazz) {
    return (T) map.get(clazz.getName());
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> T getBean(String id) {
    return (T) map.get(id);
  }

  abstract public void addObjectToContext(Class<?> c, Object o);

  public ApplicationContext load() {
    return load(null);
  }

  public ApplicationContext load(String file) {
    try {
      map = new HashMap<String, Object>();
      beanReader = AnnotationBeanReader.getInstance().load(file);
      final Set<Class<?>> classes = beanReader.getClasses();
      init(classes);
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
    return this;
  }

  private void init(Set<Class<?>> classes) throws InstantiationException,
      IllegalAccessException, IllegalArgumentException,
      InvocationTargetException {
    List<Object> instanceList = new ArrayList<Object>();
    for (Class<?> c : classes) {
      Object o = c.newInstance();
      instanceList.add(o);

      // 增加声明的组件到 ApplicationContext
      Set<String> keys = getInstanceMapKeys(c);
      for (String k : keys) {
        // log.info("obj key [{}]", k);
        map.put(k, o);
      }

      // 增加其他对象到Context
      addObjectToContext(c, o);
    }

    for (Object o : instanceList) {
      // 属性注入
      Field[] fields = o.getClass().getDeclaredFields();
      List<Field> fieldList = getInjectField(fields);
      for (Field field : fieldList) {
        field.setAccessible(true);
        Class<?> clazz = field.getType();
        String key = field.getAnnotation(Inject.class).value();
        Object instance = map.get(key.length() > 0 ? key : clazz
            .getName());
        if (instance != null)
          field.set(o, instance);
      }

      // 从方法注入
      Method[] methods = o.getClass().getDeclaredMethods();
      List<Method> methodList = getInjectMethod(methods);
      for (Method method : methodList) {
        method.setAccessible(true);
        Class<?>[] params = method.getParameterTypes();
        Object[] p = new Object[params.length];
        for (int i = 0; i < p.length; i++) {
          Object instance = map.get(params[i].getName());
          if (instance != null) {
            p[i] = instance;
          }
        }
        method.invoke(o, p);
      }
    }
  }

  private List<Method> getInjectMethod(Method[] methods) {
    List<Method> list = new ArrayList<Method>();
    for (Method m : methods) {
      if (m.isAnnotationPresent(Inject.class)) {
        list.add(m);
      }
    }
    return list;
  }

  /**
   * 找出组件的域里面包含Inject注释的域
   *
   * @param fields
   * @return
   */
  private List<Field> getInjectField(Field[] fields) {
    List<Field> list = new ArrayList<Field>();
    for (Field field : fields) {
      if (field.getAnnotation(Inject.class) != null) {
        list.add(field);
      }
    }
    return list;
  }

  /**
   * 获取声明组件的所有访问key
   *
   * @param c
   * @return
   */
  private Set<String> getInstanceMapKeys(Class<?> c) {
    Set<String> ret = new LinkedHashSet<String>();
    // 直接把类名作为key
    ret.add(c.getName());

    // 把该类实现的接口名作为key
    Class<?>[] interfaces = c.getInterfaces();
    for (Class<?> i : interfaces) {
      ret.add(i.getName());
    }

    // 把annotation的值作为key
    Controller controller = c.getAnnotation(Controller.class);
    if (controller != null && controller.value().length() > 0)
      ret.add(controller.value());
    Component component = c.getAnnotation(Component.class);
    if (component != null && component.value().length() > 0)
      ret.add(component.value());
    Interceptor interceptor = c.getAnnotation(Interceptor.class);
    if (interceptor != null && interceptor.value().length() > 0)
      ret.add(interceptor.value());
    return ret;
  }

}
TOP

Related Classes of com.firefly.core.AbstractApplicationContext

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.