आप स्थैतिक क्षेत्रों के साथ @Autowired का उपयोग कर सकते हैं?


148

क्या @Autowiredस्थैतिक क्षेत्रों के साथ उपयोग करने का कोई तरीका है । यदि नहीं, तो क्या ऐसा करने के कुछ अन्य तरीके हैं?


जवाबों:


122

संक्षेप में, नहीं। आप स्प्रिंग में स्थैतिक फ़ील्ड्स को स्वतः लोड या तार नहीं कर सकते हैं। ऐसा करने के लिए आपको अपना तर्क लिखना होगा।


3
जब आप पुराने कोड को ऐसा करते हुए पाते हैं, तो यह एक विरोधी पैटर्न है। स्क्विंट, अपने सिर को झुकाएं, और समस्या को हल करने का एक बेहतर तरीका खोजें। आपको खुशी होगी कि आपने किया।
जोसेफ वासना

2
यह उत्तर स्प्रिंग@AutoWired
केविन मेरेडिथ

116
@Component("NewClass")
public class NewClass{
    private static SomeThing someThing;

    @Autowired
    public void setSomeThing(SomeThing someThing){
        NewClass.someThing = someThing;
    }
}

1
किसी भी विचार कैसे मैं इस दृष्टिकोण का उपयोग कर सकते हैं जब एक भंडार प्रारंभिक?
kiedysktos

3
नकारात्मक पक्ष: कोई गारंटी नहीं है कि someThingअगर इसे वैधानिक रूप से एक्सेस किया गया है तो इसे इनिशियलाइज़ किया गया है: NewClass.staticMethodWhichUsesSomething();यदि ऐप इनिशियलाइज़ेशन से पहले उपयोग किया जाता है तो एनपीई फेंक सकता है
नीरज

क्या आप चेतावनी से बच सकते हैं Instance methods should not write to "static" fields (squid:S2696)?
user7294900

@ user7294900: इस चेतावनी को केवल इसके लिए अक्षम करें, बहुत विशिष्ट मामला।
izogfif

@izogfif अभी भी एक समस्या है अगर मैं व्यापक मामलों और कक्षाओं में इस समाधान का चयन करता हूं
user7294900

67

@Autowired बसने के साथ इस्तेमाल किया जा सकता है ताकि आप एक स्थिर क्षेत्र को संशोधित करने वाला एक सेटर कर सकें।

बस एक अंतिम सुझाव ... नहीं


54
आप ऐसा क्यों नहीं करने का सुझाव देते हैं?
जॉन लोरसो

3
हम्मम .. इस बारे में मेरी भावना कि इसकी सिफारिश क्यों नहीं की गई है, क्योंकि तब वर्ग में स्थिर उदाहरण वसंत के नियंत्रण से परे है। एक बार इंजेक्शन स्थिर क्षेत्र है इसी (आसपास) वर्ग की वस्तुओं के सभी उदाहरणों के लिए संदर्भ। लेकिन, यह व्यवहार ठीक वैसा ही हो सकता है जैसा कि होने की उम्मीद है, इस प्रकार इसे बग या फीचर के रूप में देखा जा सकता है ...
मैथ्यूस

1
: हाँ @matthaeus, यह वास्तव में सुविधा मैं उम्मीद जब पहुँच org.springframework.core.env.Environment करने की जरूरत है@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
user1767316

@ जोंलोरसो और सभी क्योंकि जब क्लास लोडर स्थिर मूल्यों को लोड करता है, तो वसंत संदर्भ अभी तक आवश्यक लोड नहीं होता है। इसलिए क्लास लोडर बीन में स्थिर वर्ग को ठीक से इंजेक्ट नहीं करेगा और विफल हो जाएगा। एंड्रिया टी द्वारा प्रदान किया गया उत्तर
जेरिल कुरुविला

14

@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)?
user7294900

आप इसे सीधे कंस्ट्रक्टर के माध्यम से भी कर सकते हैं।
गागरवा

5

एक बीन बनाएँ जिसे आप स्वेच्छा से रोक सकते हैं जो एक स्थिर प्रभाव के रूप में स्थैतिक चर को इनिशियलाइज़ करेगा।


4

आप XML संकेतन और का उपयोग कर इसे प्राप्त कर सकते हैं MethodInvokingFactoryBean। एक उदाहरण के लिए यहां देखें

private static StaticBean staticBean;

public void setStaticBean(StaticBean staticBean) {
   StaticBean.staticBean = staticBean;
}

आपको स्प्रिंग इंजेक्शन का उपयोग करने का लक्ष्य बनाना चाहिए जहां यह अनुशंसित दृष्टिकोण है लेकिन यह हमेशा संभव नहीं है क्योंकि मुझे यकीन है कि आप कल्पना कर सकते हैं कि सब कुछ वसंत कंटेनर से नहीं खींचा जा सकता है या आप शायद विरासत प्रणालियों से निपट सकते हैं।

इस दृष्टिकोण के साथ नोट परीक्षण भी अधिक कठिन हो सकता है।


1

आप 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);

1

ऑटो वायरिंग स्टैटिक फ़ील्ड (या स्थिर) के उत्तरों को जोड़ना चाहते हैं, लेकिन इसे भी नज़रअंदाज़ नहीं किया जाएगा:

@Autowired
private static String staticField = "staticValue";

0

अस्वीकरण यह किसी भी तरह से मानक नहीं है और ऐसा करने का एक बेहतर वसंत तरीका हो सकता है। उपर्युक्त उत्तरों में से कोई भी सार्वजनिक स्थैतिक क्षेत्र वायरिंग के मुद्दों को संबोधित नहीं करता है।

मैं तीन चीजों को पूरा करना चाहता था।

  1. "ऑटोवायर" (Im @Value का उपयोग करके) वसंत का उपयोग करें
  2. एक सार्वजनिक स्थैतिक मूल्य को उजागर करें
  3. संशोधन को रोकें

मेरी वस्तु इस तरह दिखती है

private static String BRANCH = "testBranch";

@Value("${content.client.branch}")
public void finalSetBranch(String branch) {
    BRANCH = branch;
}

public static String BRANCH() {
    return BRANCH;
}

हमने 1 और 2 को पहले ही चेक कर लिया है कि हम सेटर को कॉल कैसे रोकते हैं, क्योंकि हम इसे छिपा नहीं सकते हैं।

@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;
    }
}

यह पहलू अंतिम के साथ शुरुआत करने वाले सभी तरीकों को लपेट देगा और यदि उन्हें बुलाया जाता है तो एक त्रुटि को फेंक देगा।

मुझे नहीं लगता कि यह विशेष रूप से उपयोगी है, लेकिन अगर आप ओड हैं और आपको मटर और गाजर अलग रखना पसंद करते हैं तो यह सुरक्षित रूप से करने का एक तरीका है।

जब कोई फ़ंक्शन कॉल करता है तो महत्वपूर्ण स्प्रिंग आपके पहलुओं को कॉल नहीं करता है। इसे आसान बना दिया, बुरा करने के लिए मैंने तर्क दिया कि इससे पहले कि यह समझ में आए।


-1
private static UserService userService = ApplicationContextHolder.getContext().getBean(UserService.class);

2
हालांकि यह कोड प्रश्न को हल कर सकता है, जिसमें यह भी बताया गया है कि यह समस्या कैसे और क्यों हल करती है, इससे वास्तव में आपके पोस्ट की गुणवत्ता को बेहतर बनाने में मदद मिलेगी, और संभवत: अधिक वोट मिले। याद रखें कि आप भविष्य में पाठकों के लिए सवाल का जवाब दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है। कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें और संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं।
डबल बीप

मुझे लगता है कि इस उत्तर को किसी स्पष्टीकरण की आवश्यकता नहीं हो सकती है।
चकलादार असफाक आरिफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.