আপনি কি স্ট্যাটিক ফিল্ড সহ অটোয়ার্ড ব্যবহার করতে পারবেন?


148

@Autowiredস্থির ক্ষেত্রগুলির সাথে ব্যবহার করার কোনও উপায় আছে ? যদি তা না হয় তবে এটি করার আরও কিছু উপায় আছে?


stackoverflow.com/questions/10938529/... সাথে সম্পর্কিত
pramodc84

উত্তর:


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

@ আইজোগফিফ এখনও সমস্যা আছে যদি আমি এই সমাধানটি ব্রড কেস এবং ক্লাসে বেছে
নিই

67

@Autowired সেটটারগুলির সাথে ব্যবহার করা যেতে পারে যাতে আপনার কোনও স্ট্যাটিক ক্ষেত্র পরিবর্তন করে একটি সেটার থাকতে পারে।

কেবল একটি চূড়ান্ত পরামর্শ ... না


54
আপনি এটি না করার পরামর্শ দিচ্ছেন কেন?
জন লোরুসো

3
হুমম .. কেন এটি সুপারিশ করা হয়নি তা সম্পর্কে আমার অনুভূতি হ'ল কারণ শ্রেণিতে স্থির দৃষ্টান্তটি বসন্তের নিয়ন্ত্রণের বাইরে। একবার ইনজেকশনের স্ট্যাটিক ক্ষেত্র সংশ্লিষ্ট (পার্শ্ববর্তী) ক্লাসের বস্তুর সমস্ত উদাহরণ জন্য রেফারেন্স। তবে, এই আচরণটি সম্ভবত যা ঘটবে বলে প্রত্যাশা করা হয়, তেমনি বাগ বা বৈশিষ্ট্য হিসাবে দেখা যেতে পারে ...
ম্যাথিউয়াস

1
হ্যাঁ @ ম্যামথিউস, org.springframework.core.env.Nv.Nv পরিবেশনের অ্যাক্সেস করার দরকার হওয়ার সময় এটি ঠিক বৈশিষ্ট্যটিই আমি প্রত্যাশা করেছিলাম: পরিবেশ:@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
ব্যবহারকারী 1767316

@ জোনলরোসো এবং সমস্ত কারণ যখন শ্রেণি লোডার স্থির মানগুলি লোড করে, তখন বসন্তের প্রসঙ্গটি এখনও লোড হওয়া প্রয়োজনীয় নয়। সুতরাং শ্রেণি লোডার সঠিকভাবে বিনের মধ্যে স্ট্যাটিক ক্লাসটি ইনজেক্ট করবে না এবং ব্যর্থ হবে। Andrea T
জেরিল কুরুভিলা

14

@ পোস্টকন্সট্রাক্ট পদ্ধতিতে আপনার স্বতঃশক্তিযুক্ত উপাদানটি চালু করুন

@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

আপনি এক্সএমএল স্বরলিপি এবং এটি ব্যবহার করে এটি অর্জন করতে পারেন MethodInvokingFactoryBean। উদাহরণস্বরূপ এখানে দেখুন ।

private static StaticBean staticBean;

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

আপনার প্রস্তাব করা উচিত যেখানে স্প্রিং ইনজেকশন ব্যবহার করা সম্ভব সেখানে এটি প্রস্তাবিত পদ্ধতির কারণ এটি সর্বদা সম্ভব নয় কারণ আমি নিশ্চিত যে আপনি ধারণা করতে পারেন যে বসন্তের ধারক থেকে সমস্ত কিছুই টানা যায় না বা আপনি সম্ভবত উত্তরাধিকার ব্যবস্থা নিয়ে কাজ করছেন dealing

এই পদ্ধতির সাথে নোট পরীক্ষা করা আরও কঠিন হতে পারে।


1

আপনি অ্যাপ্লিকেশনসন্টেক্সটওয়্যারটি ব্যবহার করতে পারেন

@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. "অটোয়ার" এ বসন্ত ব্যবহার করুন (আমি @ ভ্যালু ব্যবহার করছি)
  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
এই কোডটি কীভাবে এবং কেন এই সমস্যার সমাধান করে তার ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে যদিও আপনার পোস্টের গুণমান উন্নত করতে সত্যই সহায়তা করবে এবং সম্ভবত আরও বেশি ভোটের ফলাফল হবে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, কেবল এখনই জিজ্ঞাসা করা ব্যক্তি নয়। দয়া করে সম্পাদনা ব্যাখ্যা যোগ করতে পারেন এবং সীমাবদ্ধতা এবং অনুমানের কি প্রয়োগ একটি ইঙ্গিত দিতে আপনার উত্তর।
ডাবল-বিপ

আমি মনে করি এই উত্তরটির কোনও ব্যাখ্যা দেওয়ার প্রয়োজন নেই।
চাকলাদার আসফাক আরেফে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.