มีวิธีใช้@Autowiredกับฟิลด์สแตติกหรือไม่ ถ้าไม่มีวิธีอื่นที่จะทำเช่นนี้?
มีวิธีใช้@Autowiredกับฟิลด์สแตติกหรือไม่ ถ้าไม่มีวิธีอื่นที่จะทำเช่นนี้?
คำตอบ:
ในระยะสั้นไม่มี คุณไม่สามารถอัตโนมัติหรือผูกสายฟิลด์คงที่ด้วยตนเองในฤดูใบไม้ผลิ คุณจะต้องเขียนตรรกะของคุณเองเพื่อทำสิ่งนี้
@AutoWired
                    @Component("NewClass")
public class NewClass{
    private static SomeThing someThing;
    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}
              someThingได้รับการเริ่มต้นถ้าเข้าถึงแบบคงที่: NewClass.staticMethodWhichUsesSomething();อาจโยน NPE ถ้าใช้ก่อนการเริ่มต้นแอป
                    Instance methods should not write to "static" fields (squid:S2696)หรือไม่?
                    @Autowired สามารถใช้กับตัวตั้งค่าเพื่อให้คุณสามารถตั้งค่าตัวปรับเปลี่ยนฟิลด์แบบคงที่
ข้อเสนอแนะสุดท้ายเพียงข้อเดียว ... ไม่
@Component public class SpringAppEnv{ public static Environment _env; @Autowired     public void setEnv(Environment env) {_env = env;}  }
                    เริ่มส่วนประกอบที่เป็นอัตโนมัติในเมธอด @PostConstruct
@Component
public class TestClass {
   private static AutowiredTypeComponent component;
   @Autowired
   private AutowiredTypeComponent autowiredComponent;
   @PostConstruct
   private void init() {
      component = this.autowiredComponent;
   }
   public static void testMethod() {
      component.callTestMethod();
   }
}
              Instance methods should not write to "static" fields (squid:S2696)หรือไม่?
                    สร้าง bean ที่คุณสามารถ autowire ซึ่งจะเริ่มต้นตัวแปรคงที่เป็นผลข้างเคียง
คุณสามารถบรรลุนี้โดยใช้สัญกรณ์ XMLMethodInvokingFactoryBeanและ สำหรับตัวอย่างดูที่นี่
private static StaticBean staticBean;
public void setStaticBean(StaticBean staticBean) {
   StaticBean.staticBean = staticBean;
}
คุณควรตั้งเป้าหมายที่จะใช้สปริงสปริงเนื่องจากเป็นวิธีที่แนะนำแต่มันไม่ได้เป็นไปได้เสมอเพราะฉันแน่ใจว่าคุณสามารถจินตนาการได้ว่าไม่ใช่ทุกสิ่งที่สามารถดึงออกมาจากสปริงคอนเทนเนอร์หรือคุณอาจจัดการกับระบบเดิม
การทดสอบหมายเหตุอาจทำได้ยากขึ้นด้วยวิธีนี้
ต้องการเพิ่มคำตอบว่าจะไม่สนใจฟิลด์การวางสายอัตโนมัติ (หรือค่าคงที่) แต่จะไม่สร้างข้อผิดพลาดใด ๆ :
@Autowired
private static String staticField = "staticValue";
              คุณสามารถใช้ ApplicationContextAware
@Component
public class AppContext implements ApplicationContextAware{
    public static ApplicationContext applicationContext;
    public AppBeans(){
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
แล้วก็
static ABean bean = AppContext.applicationContext.getBean("aBean",ABean.class);
              ข้อจำกัดความรับผิดชอบนี่ไม่ใช่มาตรฐานและอาจเป็นวิธีที่ดีกว่าในการทำสิ่งนี้ ไม่มีคำตอบใดที่กล่าวถึงปัญหาของการเดินสายในเขตข้อมูลสาธารณะ
ฉันต้องการทำสามสิ่งให้สำเร็จ
วัตถุของฉันมีลักษณะเช่นนี้
private static String BRANCH = "testBranch";
@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
    BRANCH = branch;
}
public static String BRANCH() {
    return BRANCH;
}
เราได้ตรวจสอบ 1 และ 2 แล้วตอนนี้เราจะป้องกันการโทรไปยัง setter ได้อย่างไรเนื่องจากเราไม่สามารถซ่อนมันได้
@Component
@Aspect
public class FinalAutowiredHelper {
@Before("finalMethods()")
public void beforeFinal(JoinPoint joinPoint) {
    throw new FinalAutowiredHelper().new ModifySudoFinalError("");
}
@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")
public void finalMethods() {}
public class ModifySudoFinalError extends Error {
    private String msg;
    public ModifySudoFinalError(String msg) {
        this.msg = msg;
    }
    @Override
    public String getMessage() {
        return "Attempted modification of a final property: " + msg;
    }
}
กว้างยาวนี้จะห่อวิธีทั้งหมดที่เริ่มต้นด้วยขั้นสุดท้ายและโยนข้อผิดพลาดถ้าพวกเขาถูกเรียกว่า
ฉันไม่คิดว่ามันจะมีประโยชน์เป็นพิเศษ แต่ถ้าคุณเป็น ocd และอยากให้คุณแยกถั่วกับแครอทนี่เป็นวิธีหนึ่งที่จะทำได้อย่างปลอดภัย
สิ่งสำคัญ Spring ไม่เรียกลักษณะของคุณเมื่อเรียกใช้ฟังก์ชัน ทำให้เรื่องนี้ง่ายขึ้นแย่ไปกว่านั้นฉันก็หาตรรกะก่อนที่จะหามัน
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);