java - 如何进行动态方法调用?

标签 java spring

有一个包含许多 getter 和 setter 的类:

@Entity
@Table(name = "valeur_indicateur")
public class ValeurIndicateur {

    @Id
    @SequenceGenerator(name="s_valeur_indicateur", sequenceName="s_valeur_indicateur", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_valeur_indicateur")
    @Column(name = "val_indi_code")
    private Integer code;

    @ManyToOne
    @JoinColumn(name = "indi_code")
    private Indicateur indicateur;

    @ManyToOne
    @JoinColumn(name = "peri_mes_code")
    private PeriodiciteMesure periodicite_mesure;

    @Column(name = "val_indi_cible_1")
    private String cible_1;

    @Column(name = "val_indi_cible_2")
    private String cible_2;

    @Column(name = "val_indi_cible_3")
    private String cible_3;

    @Column(name = "val_indi_cible_4")
    private String cible_4;

    @Column(name = "val_indi_cible_5")
    private String cible_5;

    @Column(name = "val_indi_cible_6")
    private String cible_6;

    @Column(name = "val_indi_cible_7")
    private String cible_7;

    @Column(name = "val_indi_cible_8")
    private String cible_8;

    @Column(name = "val_indi_cible_9")
    private String cible_9;

    @Column(name = "val_indi_cible_10")
    private String cible_10;

    @Column(name = "val_indi_cible_11")
    private String cible_11;

    @Column(name = "val_indi_cible_12")
    private String cible_12;

    @Column(name = "val_indi_realise_1")
    private String realise_1;

    @Column(name = "val_indi_realise_2")
    private String realise_2;

    @Column(name = "val_indi_realise_3")
    private String realise_3;

    @Column(name = "val_indi_realise_4")
    private String realise_4;

    @Column(name = "val_indi_realise_5")
    private String realise_5;

    @Column(name = "val_indi_realise_6")
    private String realise_6;

    @Column(name = "val_indi_realise_7")
    private String realise_7;

    @Column(name = "val_indi_realise_8")
    private String realise_8;

    @Column(name = "val_indi_realise_9")
    private String realise_9;

    @Column(name = "val_indi_realise_10")
    private String realise_10;

    @Column(name = "val_indi_realise_11")
    private String realise_11;

    @Column(name = "val_indi_realise_12")
    private String realise_12;

    @Column(name = "val_indi_taux")
    private Integer taux;

    public ValeurIndicateur() {
        super();
        // TODO Auto-generated constructor stub
    }

    public ValeurIndicateur(Integer code) {
        super();
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Indicateur getIndicateur() {
        return indicateur;
    }

    public void setIndicateur(Indicateur indicateur) {
        this.indicateur = indicateur;
    }

    public PeriodiciteMesure getPeriodicite_mesure() {
        return periodicite_mesure;
    }

    public void setPeriodicite_mesure(PeriodiciteMesure periodicite_mesure) {
        this.periodicite_mesure = periodicite_mesure;
    }

    public String getCible_1() {
        return cible_1;
    }

    public void setCible_1(String cible_1) {
        this.cible_1 = cible_1;
    }

    public String getCible_2() {
        return cible_2;
    }

    public void setCible_2(String cible_2) {
        this.cible_2 = cible_2;
    }

    public String getCible_3() {
        return cible_3;
    }

    public void setCible_3(String cible_3) {
        this.cible_3 = cible_3;
    }

    public String getCible_4() {
        return cible_4;
    }

    public void setCible_4(String cible_4) {
        this.cible_4 = cible_4;
    }

    public String getCible_5() {
        return cible_5;
    }

    public void setCible_5(String cible_5) {
        this.cible_5 = cible_5;
    }

    public String getCible_6() {
        return cible_6;
    }

    public void setCible_6(String cible_6) {
        this.cible_6 = cible_6;
    }

    public String getCible_7() {
        return cible_7;
    }

    public void setCible_7(String cible_7) {
        this.cible_7 = cible_7;
    }

    public String getCible_8() {
        return cible_8;
    }

    public void setCible_8(String cible_8) {
        this.cible_8 = cible_8;
    }

    public String getCible_9() {
        return cible_9;
    }

    public void setCible_9(String cible_9) {
        this.cible_9 = cible_9;
    }

    public String getCible_10() {
        return cible_10;
    }

    public void setCible_10(String cible_10) {
        this.cible_10 = cible_10;
    }

    public String getCible_11() {
        return cible_11;
    }

    public void setCible_11(String cible_11) {
        this.cible_11 = cible_11;
    }

    public String getCible_12() {
        return cible_12;
    }

    public void setCible_12(String cible_12) {
        this.cible_12 = cible_12;
    }

    public String getRealise_1() {
        return realise_1;
    }

    public void setRealise_1(String realise_1) {
        this.realise_1 = realise_1;
    }

    public String getRealise_2() {
        return realise_2;
    }

    public void setRealise_2(String realise_2) {
        this.realise_2 = realise_2;
    }

    public String getRealise_3() {
        return realise_3;
    }

    public void setRealise_3(String realise_3) {
        this.realise_3 = realise_3;
    }

    public String getRealise_4() {
        return realise_4;
    }

    public void setRealise_4(String realise_4) {
        this.realise_4 = realise_4;
    }

    public String getRealise_5() {
        return realise_5;
    }

    public void setRealise_5(String realise_5) {
        this.realise_5 = realise_5;
    }

    public String getRealise_6() {
        return realise_6;
    }

    public void setRealise_6(String realise_6) {
        this.realise_6 = realise_6;
    }

    public String getRealise_7() {
        return realise_7;
    }

    public void setRealise_7(String realise_7) {
        this.realise_7 = realise_7;
    }

    public String getRealise_8() {
        return realise_8;
    }

    public void setRealise_8(String realise_8) {
        this.realise_8 = realise_8;
    }

    public String getRealise_9() {
        return realise_9;
    }

    public void setRealise_9(String realise_9) {
        this.realise_9 = realise_9;
    }

    public String getRealise_10() {
        return realise_10;
    }

    public void setRealise_10(String realise_10) {
        this.realise_10 = realise_10;
    }

    public String getRealise_11() {
        return realise_11;
    }

    public void setRealise_11(String realise_11) {
        this.realise_11 = realise_11;
    }

    public String getRealise_12() {
        return realise_12;
    }

    public void setRealise_12(String realise_12) {
        this.realise_12 = realise_12;
    }

    public Integer getTaux() {
        return taux;
    }

    public void setTaux(Integer taux) {
        this.taux = taux;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return code.toString();
    }

}

我想从 1 到 12 调用 setter setCible_ :

@RequestMapping(value = "/insertIndicateur", method = RequestMethod.POST)
public ModelAndView insertIndicateur(@ModelAttribute("indicateur_formulaire") Indicateur indicateur,
                                    @RequestParam int f_objectif,
                                    @RequestParam int f_nature_indicateur,
                                    @RequestParam String f_periodicite_mesure,
                                    @RequestParam String f_type_sortie,
                                    @RequestParam String acteur_saisie,
                                    @RequestParam String acteur_verif,
                                    @RequestParam Map<String, String> params,
                                    HttpServletRequest request, HttpSession session) {

    indicateurDao.insert(indicateur, f_objectif, f_nature_indicateur, f_periodicite_mesure, f_type_sortie, acteur_saisie, acteur_verif);

    ValeurIndicateur valeurIndicateur = new ValeurIndicateur();

    switch(f_periodicite_mesure) {
        case "ANN":
            valeurIndicateur.setCible_1(params.get("val_indi_cible_1"));
            break;
        case "SEM":
            valeurIndicateur.setCible_1(params.get("val_indi_cible_1"));
            valeurIndicateur.setCible_2(params.get("val_indi_cible_2"));
            break;
        case "TRI":
            valeurIndicateur.setCible_1(params.get("val_indi_cible_1"));
            valeurIndicateur.setCible_2(params.get("val_indi_cible_2"));
            valeurIndicateur.setCible_3(params.get("val_indi_cible_3"));
            valeurIndicateur.setCible_4(params.get("val_indi_cible_4"));
            break;
        case "MEN":

            // here I want to loop from 1 to 12 and call dynamically valeurIndicateur.setCible_

            break;
    }

    valeurIndicateur.setIndicateur(indicateur);
    valeurIndicateur.setPeriodicite_mesure(periodiciteMesureDao.get(f_periodicite_mesure));

    valeurIndicateurDao.insert(valeurIndicateur);

    ModelAndView modelView = new ModelAndView("redirect:/elaboration/");

    return modelView;

}

有没有办法动态调用它们?

最佳答案

如果您的对象符合 JavaBeans 规范,那么(当您使用 Spring 时),BeanWrapper界面可能是您最好的选择:

BeanWrapper beanWrapper = new BeanWrapperImpl(yourObject);
Arrays.stream(beanWrapper.getPropertyDescriptors())
      .map(PropertyDescriptor::getName)
      .forEach(name-> beanWrapper.setPropertyValue(name, attributes.get(name))
);

请注意,JavaBeans 属性名称“foo”指向方法“setFoo”和“getFoo”。

或者,如果您想迭代属性映射,请这样做:

BeanWrapper beanWrapper = new BeanWrapperImpl(yourObject);
attributes.forEach((k,v)->{
    if(beanWrapper.isWritableProperty(k)) beanWrapper.setPropertyValue(k,v);
});
<小时/>

另一种没有反射的方法是使用调用方法的 BiConsumers 进行硬编码映射,如下所示:

static final Map<String, BiConsumer<YourClass,String>> PROPERTY_MAP;
static {
    Map<String, BiConsumer<YourClass,String>> map = new HashMap<>();
    map.put("val_indi_cible_1", YourClass::setCible_1);
    map.put("val_indi_cible_2", YourClass::setCible_2);
    map.put("val_indi_cible_3", YourClass::setCible_3);
    map.put("val_indi_cible_4", YourClass::setCible_3);
    map.put("val_indi_cible_5", YourClass::setCible_4);
    map.put("val_indi_cible_6", YourClass::setCible_5);
    // etc.
    PROPERTY_MAP= Collections.unmodifiableMap(map);
}

现在,在您的方法中,您可以执行以下操作:

YourClass yourClass = new YourClass();
attributes.forEach((k, v) -> Optional.ofNullable(PROPERTY_MAP.get(k))
                                     .ifPresent(bc -> bc.accept(yourClass, v)));

说明:

  • 迭代属性映射
  • 对于每个键,查看是否有关联的属性
  • 如果存在,请调用该属性

优点:无反射、性能不错、编译时安全

缺点:每当添加新方法时都必须更新属性映射

关于java - 如何进行动态方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43141828/

相关文章:

java - @autowired on Spring 中的方法

java - MockMVC 和 Mockito 返回状态预期 <200> 但为 <415>

java - 从 python/django 学习 java/spring

java - 在 Jframe 图像上绘制

java - Java 中的系统语句是什么意思?

java - 如何为基于 spring 的 Rest api 和静态内容添加安全性

java - Spring & JUnit : Spring instantiates two instances of test class, 仅注入(inject)其中一个的依赖项,运行另一个

spring - Resteasy-Spring : incorrect app instance loaded during tests with multiple running instances

java - 无需本地化的 Android 多语言支持

Java:从另一个类调用实例化 getter 返回 null