Java依赖注入多个对象

时间:2018-10-13 12:12:13

标签: java dependency-injection

我想在类中使用带有@Inject批注的同一对象。

因此在此测试中:我需要向Test和C类中注入相同的'b'对象。

我的DefaultBeanFactory有什么问题?

这是我的测试主要课程(注入A,B和C):

public class Test {

        @Inject
        private A a;

        @Inject
        private B b;

        @Inject
        private C c;

        public static void main(String [] arg) {
            BeanFactory f = new DefaultBeanFactory();
            f.registerBean(Test.class.getName());
            Test test = (Test)f.getBean("Test");
            test.start();
        }

        private void start() {
            c.tryTosetB();
            System.out.println("b in: '"+this.getClass().getName()+"' with id["+b.getId()+"] with hashcode: ["+b.hashCode()+"]");
            c.printB();
        }
    }

注入的类:

A(注入A):

public class A {
@Inject
private B b;

public A(){
    System.out.println("A constructor");
}

}

B:

public class B {

private String id;

public B(){
    System.out.println("B constructor");
}

public void setId(String id) {
    this.id = id;
}

public String getId() {
    return id;
}

}

C(注入B):

public class C {

@Inject
private B b;

public C(){
    System.out.println("A constructor");
}

public void tryTosetB(){
    b.setId("C setted id");
}

public void printB(){
    System.out.println("b in: '"+this.getClass().getName()+"' with id["+b.getId()+"] with hashcode: ["+b.hashCode()+"]");
}

}

这是我的BeanFactory:

public class DefaultBeanFactory implements BeanFactory {

private static final Map<String, BeanDefinition> BEAN_DEF_MAP = new HashMap<>();

public static Map<String, BeanDefinition> getBeanDefMap() {
    return BEAN_DEF_MAP;
}

public static Map<String, Object> getSingletonMap() {
    return SINGLETON_MAP;
}

private static final Map<String, Object> SINGLETON_MAP = new HashMap<String, Object>();

private static String generateBeanId(String className) {
    return className.substring(className.lastIndexOf('.') + 1, className.length());
}

@Override
public void registerBean(String classname) {
    registerBean(classname, Scope.SINGLETON);
}

@Override
public void registerBean(String classname, Scope scope) {

    System.out.println("Register been: "+classname +" "+scope.name());

    String beanId = generateBeanId(classname);

    if (BEAN_DEF_MAP.containsKey(beanId)) {
        System.out.println("Bean already registered to the container {" + beanId + "}");
        return;
    }

    BeanDefinition def = new BeanDefinition();
    def.setClassFqdn(classname);
    def.setId(beanId);
    def.setScope(scope);

    BEAN_DEF_MAP.put(beanId, def);

}

@Override
public Object getBean(String id) {
    System.out.println("Request to get Bean with id: "+id);
    BeanDefinition def = BEAN_DEF_MAP.get(id);

    if (def == null) {
        throw new IllegalArgumentException("Missing bean from the container with id: " + id);
    }else{
        System.out.println("\tBean found in BEAN_DEF_MAP with id: "+id);
    }

    Object instance = null;

    if (Scope.SINGLETON == def.getScope()) {

        if (SINGLETON_MAP.containsKey(id)) {
            System.out.println("\tSINGLETON_MAP contained: "+id);
            instance = SINGLETON_MAP.get(id);
        } else {
            System.out.println("\tSINGLETON_MAP not contained so create object: "+def+ " with id: "+id);
            instance = createObject(def);
            SINGLETON_MAP.put(id, instance);

        }
    } else if (Scope.PROTOTYPE == def.getScope()) {

        instance = createObject(def);
    }

    return instance;
}

private static void injectDependencies(Object containerObject, Field f) {
    System.out.println("Request to inject field with name: "+f.getName());

    if ((f.getAnnotation(Inject.class) != null) && !f.getClass().isPrimitive()) {
        System.out.println("\t@Inject: "+f.getType().getName());
        Object fieldValue = null;

        try {
            fieldValue = f.getType().newInstance();
            f.setAccessible(true);
            f.set(containerObject, fieldValue);

            for (Field transitiveDependency : f.getType().getDeclaredFields()) {
                injectDependencies(fieldValue, transitiveDependency);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private static List<Field> getAllField(List<Field> fields, Class<?> clazz) {

    List<Field> allField = new ArrayList<Field>();

    allField.addAll(Arrays.asList(clazz.getDeclaredFields()));

    if (clazz.getSuperclass() != null) {

        allField.addAll(getAllField(allField, clazz.getSuperclass()));
    }

    return allField;
}

private static Object createObject(BeanDefinition def) {
    System.out.println("Request to get create Object with def class: "+def.getClassFqdn());
    Object instance = null;
    Class<?> beanClazz = null;
    try {
        beanClazz = Class.forName(def.getClassFqdn());
        instance = beanClazz.newInstance();
        List<Field> fields = getAllField(new ArrayList<Field>(), beanClazz);

        for (Field f : fields) {
            System.out.println("\tinject dependencie field with name: "+f.getName());
            injectDependencies(instance, f);
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return instance;
}

0 个答案:

没有答案