Динамически созданный Java-файл RestController с Javassist можно назвать? - PullRequest
2 голосов
/ 06 ноября 2019

Я экспериментирую, можно ли вызвать файл почтальона из файла контроллера, созданного javassist во время выполнения. Создание класса Java с аннотацией @RestController для класса и аннотацией Postmapping для метода. Как и следовало ожидать, он не смог позвонить от почтальона.

Мой коллега сказал, что это может быть из-за времени сканирования аннотации. Когда запускается весенняя загрузка, появляется журнал, как показано ниже, обновляющий AnnotationConfigApplicationContext, поэтому я попытался зарегистрировать bean-компонент на AnnotationConfigApplicationContext, но результат был таким же;не найдено. Так что удивляйтесь, если это вообще возможно в первую очередь.

2019-11-06 15:22:14.825 DEBUG [external-service,,,](20008)[main] [o.s.c.a.AnnotationConfigApplicationContext:590] [local] Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@72be135f
2019-11-06 15:22:14.837 DEBUG [external-service,,,](20008)[main] [o.s.b.f.s.DefaultListableBeanFactory:213] [local] Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'

Это код для создания контроллера с аннотацией.

    public Class ctClassController() throws Exception {
        CtClass ctController = this.createCtClass("ctController");
        CtMethod ctMethod = CtNewMethod.make("public String test(){ return 'testController';}", ctController);


        ClassFile cFile = ctController.getClassFile();
        ConstPool constPool = cFile.getConstPool();
        AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);

        Annotation annotation = new Annotation(RestController.class.getName(), constPool);
        attr.addAnnotation(annotation);

        annotation = new Annotation(Component.class.getName(), constPool);
        attr.addAnnotation(annotation);

        ctController.getClassFile().addAttribute(attr);


        AnnotationsAttribute attr4Method = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
        annotation = new Annotation(PostMapping.class.getName(), constPool);
        annotation.addMemberValue("value", new StringMemberValue("/api/ctController", constPool));
        attr4Method.setAnnotation(annotation);


        ctMethod.getMethodInfo().addAttribute(attr4Method);
        ctController.addMethod(ctMethod);

         ctController.toClass(this.getClass().getClassLoader(), this.getClass().getProtectionDomain());
        Class klass = Class.forName("ctController");

        return klass;

    }

, и следующее было попыткой повторно отсканировать аннотацию.

Class controllerKlass = vendorDynamicClassConstructor.ctClassController();
Object controllerObj = controllerKlass.getDeclaredConstructor().newInstance();

 AbstractApplicationContext abstractContext = new AnnotationConfigApplicationContext();

    abstractContext.refresh();

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(controllerObj.getClass());
        context.refresh();

поэтому, если я позвоню от такого почтальона, http://localhost:2028/api/ctController я хочу увидеть 'testController', однако получаю следующее. Был бы другой путь?

<Map>
    <timestamp>1573026801879</timestamp>
    <status>404</status>
    <error>Not Found</error>
    <message>No message available</message>
    <path>/api/ctController</path>
</Map>
...