简体   繁体   English

如何在运行时设置bean类

[英]How to set bean class at runtime

Example: I have a an abstract class "animal" and subclass "lion" and "tiger". 示例:我有一个抽象类“动物”和子类“狮子”和“老虎”。 Subclass name is written on NotesDocument field "Form". 子类名称写在NotesDocument字段“表单”上。 How do i create bean named animal with class "Tiger" or "Lion" at runtime. 如何在运行时使用类“ Tiger”或“ Lion”创建名为动物的bean。

My plan is: I make a bean with managed-bean-name "animal", managed-bean-class "AnimalFactory". 我的计划是:我制作一个带有托管动物名称“ animal”,托管bean类“ AnimalFactory”的bean。 Then somewhere, where?, I want to (pseudocode) 然后在某个地方,哪里?,我想(伪代码)

Document doc = database.getDocById("AAAA"); //from docId parameter
String animalType = doc.getItemValueString("Form");
if (animalType.equals("Lion") return makeLionInstance();
else return makeTigerInstance();

Can someone point me in a right direction or give me an example? 有人可以指出我正确的方向还是给我一个例子?

EDIT 编辑

I havent study any answers provided... Will do tomorrow. 我尚未研究提供的任何答案。

Problem is we have 100k-300k LoC project and noone knows what exactly it is doing. 问题是我们有100k-300k LoC项目,没人知道它到底在做什么。 It is 15 years old and had 30-50 developers. 它已经15岁了,有30-50个开发人员。 Anyway, we decided to go web. 无论如何,我们决定上网。 In java we see a great oppurtunity to rewrite project to java (as many have already done), remove redundant code, define interfaces etc (and later, where no MS objects are involved, replace java code with LS code)... We have 6 different (with similar base) doc (form)types with subtypes and every type has 5 different workflows, which are exclusive. 在Java中,我们看到了将项目重写为Java(很多人已经做过),删除冗余代码,定义接口等的巨大机会(后来,在不涉及MS对象的情况下,将Java代码替换为LS代码)...具有子类型的6种不同(具有基本基数)的doc(表单)类型,每种类型都有5种不同的工作流程,这些工作流程是互斥的。

I dont have the knowledge of how to instantiate specific class from notesdocument at runtime. 我不知道如何在运行时从notesdocument实例化特定的类。 One workaround is to provide variables to base class and instantiate them at runtime based on field "Form". 一种解决方法是为基类提供变量,并在运行时根据字段“ Form”实例化它们。 I have a feeling, this will not suffice in the long run. 我有一种感觉,从长远来看,这是不够的。

As in my "plan", I THINK I have a vague idea of what must be done. 就像在我的“计划”中一样,我认为我对必须做的事情含糊不清。 I dont know where to insert code, neither what I must be careful about. 我不知道在哪里插入代码,也不知道我要注意什么。

TL:DR TL:DR

How to have instance of type defined on document field "Form" resolved to managed bean at runtime. 如何在运行时将文档字段“ Form”上定义的类型实例解析为托管Bean。

I think this article was revolutionary at the time. 我认为这篇文章在当时是革命性的。 It helped me a lot to take control over managed beans. 这对我控制托管bean很有帮助。 Get inspired by it and make factory bean Zoo implementing Map interface. 从中得到启发,并使工厂bean Zoo实现Map接口。 Your get(String) method will instantiate or retrieve according animal object based on its name. 您的get(String)方法将根据动物对象的名称实例化或检索它。

Your EL/SSJS will be easy as: 您的EL / SSJS将很容易,因为:

#{zoo.lion}
#{javascript:zoo.get("Lion").roar()}

Factory pattern will be suffice and enhancement to this will be like initialize a map with key as the animal subclass name and value as actual instance. 工厂模式就足够了,对此的增强将类似于使用键作为动物子类名称和值作为实际实例初始化映射。

animalMap.put("Lion", LionObject);
animalMap.put("Tiger", TigerObject);

from the form get the key and return the instance. 从表单获取密钥并返回实例。 for example if the value from form is Tiger then you can get the instance like 例如,如果来自form的值是Tiger,那么您可以获得类似的实例

animalMap.get("value passed from the map") --> animalMap.get("Tiger").

There are a lot of solutions to the particular problem, and they depend on where you're going to go with it. 针对特定问题有很多解决方案,它们取决于您要解决的问题。

I would start by creating an interface AnimalFactory. 我将从创建一个接口AnimalFactory开始。

interface AnimalFactory<T extends Animal> {
    T create();
}

Then, I would create a mapping: 然后,我将创建一个映射:

private final Map<String, AnimalFactory<?>> factories = initFactories();

private Map<String, AnimalFactory<?>> initFactories() {
   final Map<String, AnimalFactory<?>> factories = new HashMap<>();
   // Note, in Java 8, you can simplify these anonymous classes to "Tiger::new" and "Lion::new".
   factories.put("lion", new AnimalFactory<Lion>() {
        public void create() { return new Lion(); }
   }); 
   factories.put("tiger", new AnimalFactory<Tiger>() {
        public void create() { return new Tiger(); }
   }); 
   return map;
}

public Animal createAnimal(String type) {
   final AnimalFactory<?> factory = factories.get(type.toLowercase());
   if (factory == null) { return null; }
   return factory.create();
}

You can use enums as a factory pattern and they are singleton also. 您可以将enums用作factory模式,它们也是singleton

package com.test;

public enum AnimalFarm {

    LION(new Lion()),
    TIGER(new Tiger());

    private Animal animal;
    private AnimalFarm(Animal animal) {
        this.animal = animal;
    }

    private static Animal getAnimalByName(String name) {
        return AnimalFarm.valueOf(name.toUpperCase()).animal;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM