有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java spring@Value注释、继承和公共字段,但值不同

我有三个类,其中一个是超类

class abstract Base {
   public abstract String getV();
}

class A extends Base {
   private String v;
   @Value("${A.v}") public String getV() { return v; };
}

class B extends Base {
   private String v;
   @Value("${B.v}") public String getV() { return v; };
}

有没有办法简化spring@Value注释的使用?我不想复制所有基子项的粘贴字段声明和getter。到目前为止,我得到的只是:

class abstract Base {
   protected String v;
   public String getV() { return v; };
   public abstract void setV(String v);
}

class A extends Base {
   @Value("${A.v}") public void setV(String v) { this.v = v;};
}

class B extends Base {
   @Value("${B.v}") public void setV(String v) { this.v = v;};
}

有没有更有效的方法?谢谢你的帮助


共 (2) 个答案

  1. # 1 楼答案

    我对此表示怀疑。注释不能是动态的。无法在抽象的setV方法上添加任何类型的注释来适应子类。你所做的是正确的选择

    不过,我会稍微修改一下您的代码:

    class Base {
       private String v;
       public String getV() { return v; };
       public void setV(String v) { this.v = v; }
    }
    
    class A extends Base {
       @Value("${A.v}") public String setV(String v) { super.setV(v); }
    }
    
    class B extends Base {
       @Value("${B.v}") public String setV(String v) { super.setV(v); }
    }
    

    我不仅在@Value注释中遇到了这个问题,在@Resource/@限定符注释中也遇到了这个问题

    这是我不太喜欢自动布线的一个重要原因。我发现自己毫无理由地创建了一堆子类,只是为了用不同的限定符/值自动连接东西

    另一种选择可能是基于java的配置。我知道这与用XML做这件事并没有太大的区别,但我发现它比XML更干净,当然也比覆盖所有的setter要好

    @Configuration
    public class MyConfig {
        @Value("${A.v}")
        private String av;
    
        @Value("${B.v}")
        private String bv;
    
        @Bean
        public A a() {
           A a = new A();
           a.setV(av);
        }
    
    
        @Bean
        public B b() {
           B b = new B();
           b.setV(bv);
        }
    }
    

    然后在XML中:

    <context:annotation-config />
    <bean class="MyConfig" />
    
  2. # 2 楼答案

    另一种方法:

    class abstract Base {
        private String v;
        protected void configure(String v) {
            this.v = v;
        }
    }
    
    class A extends Base {
        @Value("${A.v}") private String v;
    
        @SuppressWarnings("unused")
        @PostConstruct
        private void configure() {
            super.configure(v);
        }
    }
    
    class B extends Base {
        @Value("${B.v}") private String v;
    
        @SuppressWarnings("unused")        
        @PostConstruct
        private void configure() {
            super.configure(v);
        }
    }
    

    这样,如果有很多值需要在超类中设置,那么每个值只需要一个实例变量,并且可以在configure方法中设置它们。就算你没有被迫实施配置