dimanche 5 août 2018

Java Reflection How to instantiate class field type

I have the follow class that I'm trying to instantiate through reflection and then auto instantiate it's field 'databaseService'

public class BaseController {

        @AutoInstantiate
        private DatabaseService databaseService;

        @AfterSetup
        public void initRoute() {

                System.out.println("Testing " + databaseService.getEntry("test"));

                System.out.println("Request : "+req.ip());
                System.out.println(SSLUtil.getUser(req.raw()));

                SoundInvoker.playSound();

                return "Running : "+new Date();
        }
    }

What I'm trying to do

public class Instantiator {

    private static Logger logger = Logger.getLogger(Instantiator.class.getName());

    private static HashMap<Class<?>, Object> instantiatedClasses = new HashMap<>();

    private static void checkClassDepenecies(Class<?> clazz) {

        for(Field field : clazz.getDeclaredFields()) {

            if(field.isAnnotationPresent(AutoInstantiate.class)) {

                try {

                    field.setAccessible(true);

                    Object autowiredObject = field.getType().newInstance();
                    System.out.println("Class Type : " + autowiredObject.getClass().getName());

                    instantiatedClasses.put(field.getType(), autowiredObject);

                    System.out.println(autowiredObject.getClass().getName());

                    //HERES WHERE IT ALWAYS FAILS
                    field.set(field.getType(), autowiredObject);

                }
                catch(Exception e) {

                    logger.severe("Failure invoking class " + clazz.getName() + " Problem : " + e.getMessage());
                    System.exit(1);
                }
            }
        }

        instantiateComponent(clazz);
    }

    private static void instantiateComponent(Class<?> clazz) {

        if(instantiatedClasses.containsKey(clazz))
            return;

        for(Method method : clazz.getMethods()) {

            if(method.isAnnotationPresent(AfterSetup.class)) {

                try {

                    Constructor<?> constructor = clazz.getConstructors()[0];
                    constructor.setAccessible(true);
                    Object object = constructor.newInstance();

                    method.invoke(object);
                    constructor.setAccessible(false);

                    instantiatedClasses.put(clazz, object);
                }
                catch(Exception e) {

                    logger.severe("Failure invoking class " + clazz.getName() + " Problem : " + e.getMessage());
                    System.exit(1);
                }
            }
        }
    }

    public static void start() {

        Reflections reflections = new Reflections("com.services");

        for (Class<?> clazz : reflections.getTypesAnnotatedWith(Controller.class))
            checkClassDepenecies(clazz);
    }
}

And the simple main

public class App {

    public static void main(String[] args) throws Exception {

        Instantiator.start();
    }
}

Problem SEVERE: Failure invoking class com.controller.BaseController Problem : Can not set com.service.DatabaseService field com.controller.BaseController.databaseService to java.lang.Class

Overall problem: I'm not sure how to get a Class field/object and automatically instantiate it





Aucun commentaire:

Enregistrer un commentaire