কেন @ পোষ্টকনস্ট্রাক্ট ব্যবহার করবেন?


294

পরিচালিত শিমের @PostConstructমধ্যে নিয়মিত জাভা অবজেক্ট কনস্ট্রাক্টরের পরে ডাকা হয়।

আমি কেন @PostConstructনিয়মিত কনস্ট্রাক্টরের পরিবর্তে শিমের সাহায্যে আরম্ভ করতে ব্যবহার করব ?


4
আমি এই ধারণাটি পেয়েছি যে নির্ভরতা হতে দেয়ায় সাধারণত কনস্ট্রাক্টর ইঞ্জেকশন পছন্দ করা হয় final। সেই প্যাটার্নটি দেওয়া, কেন @PostConstructJ2EE এ যুক্ত করা হচ্ছে - তারা অবশ্যই অন্য একটি ব্যবহারের কেস দেখে থাকতে পারে?
mjaggard

উত্তর:


409
  • কারণ যখন কনস্ট্রাক্টরকে ডাকা হয় তখন শিমটি এখনও আরম্ভ করা হয় না - অর্থাৎ কোনও নির্ভরতা ইনজেকশন হয় না। ইন @PostConstructপদ্ধতি শিম সম্পূর্ণরূপে সক্রিয়া করা হয় এবং আপনি নির্ভরতা ব্যবহার করতে পারেন।

  • কারণ এটি এমন চুক্তি যা গ্যারান্টি দেয় যে বিন পদ্ধতিতে একবারেই এই পদ্ধতিটি চালু করা হবে। এটি ঘটতে পারে (যদিও অসম্ভব) যে কোনও শিমটি তার অভ্যন্তরীণ কাজকর্মের ক্ষেত্রে ধারক দ্বারা একাধিকবার ইনস্ট্যান্ট করা হয় তবে এটি গ্যারান্টি দেয় যে এটি @PostConstructকেবল একবারই ডাকা হবে।


17
যদি কনস্ট্রাক্টর নিজেই সমস্ত নির্ভরতা স্বতঃশক্ত করে তোলে - তবে বিনটিও কনস্ট্রাক্টরে সম্পূর্ণরূপে আরম্ভ করা যেতে পারে (ম্যানুয়ালি সমস্ত স্বয়ংক্রিয় ক্ষেত্রগুলি সেট করার পরে)।
ইয়ার

7
শিমের নির্মাতাকে একাধিকবার ডাকা যেতে পারে এমন ক্ষেত্রে কী ঘটেছে?
ইয়ায়ার

1
সম্ভবত "প্যাসিভেশন" এর মতো কিছু। কনটেইনারটি যদি ডিসটি স্টোরগুলিতে শিমটি সংরক্ষণ করার সিদ্ধান্ত নেয় এবং তারপর সেখান থেকে পুনরুদ্ধার করুন।
বোঝো

13
একাধিকবার বলা কনস্ট্রাক্টর দেখার সম্ভাবনা কম নয়। ধারক যখন একটি প্রক্সি ইনস্ট্যান্ট করে, আপনি দেখতে পাবেন যে কনস্ট্রাক্টরকে প্রক্সিটির জন্য কমপক্ষে একবার এবং আসল বিনের জন্য একবার ডাকা হয়।
মারকাস

মনে রাখবেন যে সার্ভার পুনরায় চালু হওয়ার সাথে সাথে পৃষ্ঠাটি লোড হওয়ার পরে @ পোষ্টকনস্ট্রাক্ট পদ্ধতিগুলি কল করা হয় না । (এটি জেবস বাগ হতে পারে))
ডেভ জার্ভিস

96

প্রধান সমস্যা যে:

কনস্ট্রাক্টারে, নির্ভরতার ইনজেকশনটি এখনও ঘটেনি *

* অবশ্যই কনস্ট্রাক্টর ইনজেকশন বাদ দিয়ে


বাস্তব-বিশ্বের উদাহরণ:

public class Foo {

    @Inject
    Logger LOG;

    @PostConstruct
    public void fooInit(){
        LOG.info("This will be printed; LOG has already been injected");
    }

    public Foo() {
        LOG.info("This will NOT be printed, LOG is still null");
        // NullPointerException will be thrown here
    }
}

গুরুত্বপূর্ণ : @PostConstructএবং জাভা 11 এ@PreDestroy সম্পূর্ণ অপসারণ করা হয়েছে

এগুলি ব্যবহার চালিয়ে যাওয়ার জন্য আপনাকে আপনার নির্ভরতার সাথে জাভাক্স.অনোটেশন-এপিআই জেআর যুক্ত করতে হবে ।

ম্যাভেন

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Gradle

// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'

19
in a constructor, the injection of the dependencies has not yet occurred. সেটার বা ফিল্ড ইনজেকশন সহ সত্য, তবে কনস্ট্রাক্টর ইঞ্জেকশনের সাথে সত্য নয়।
অ্যাডাম সিমিয়ন

@ পোষ্টকন্সট্রাক্টটি জাভা ১১-এ সরানো হচ্ছে, এখন আমরা কীভাবে জাভা ১১ এর মাধ্যমে এই বাস্তব বিশ্বের উদাহরণটি পরিচালনা করতে পারি?
টিইটি

@tet উত্তরে উল্লিখিত হিসাবে, আপনার javax.annotation-api লাইব্রেরি ব্যবহার করা উচিত। এই টীকাগুলিগুলি জাভা ১১-এ সরানো হয়েছে, তবে এটি জাভা ৯ এর পর থেকে
প্রত্যাখ্যানিত

63

যদি আপনার শ্রেণিটি তার আরম্ভের সমস্তটি কনস্ট্রাক্টারে সম্পাদন করে, তবে @PostConstructতা অবশ্যই অনর্থক।

যাইহোক, যদি আপনার শ্রেণীর সেটার পদ্ধতি ব্যবহার করে তার নির্ভরতা থাকে তবে শ্রেণীর নির্মাতা পুরোপুরি অবজেক্টটি আরম্ভ করতে পারবেন না, এবং কখনও কখনও সমস্ত সেটার পদ্ধতি আহ্বানের পরে কিছু সূচনা করা প্রয়োজন, সুতরাং ব্যবহারের ক্ষেত্রে @PostConstruct


@ স্টাফম্যান: আমার দিক থেকে প্লাস ওয়ান। যদি আমি ডাটাবেস থেকে প্রাপ্ত মান সহ একটি ইনপুটেক্সট ফিল্ডটি আরম্ভ করতে চাই, তবে আমি পোস্টকন্সট্রাক্টের সাহায্যে এটি করতে সক্ষম হয়েছি তবে কনস্ট্রাক্টরের অভ্যন্তরে একই কাজ করার চেষ্টা করতে ব্যর্থ হয়। পোস্টকন্ট্রাক্ট ব্যবহার না করে আমার আরম্ভ করার প্রয়োজন রয়েছে। : আপনি সময় আছে, তাহলে আপনি এই এক উত্তর দিতে দয়া করে করতে পারেন stackoverflow.com/questions/27540573/...
Shirgill ফারহান

10

নিম্নলিখিত পরিস্থিতিতে বিবেচনা করুন:

public class Car {
  @Inject
  private Engine engine;  

  public Car() {
    engine.initialize();  
  }
  ...
}

যেহেতু ফিল্ড ইঞ্জেকশন দেওয়ার আগে গাড়িটিকে তাত্ক্ষণিকভাবে চালিত করতে হয়, তাই ইঞ্জেকশন পয়েন্ট ইঞ্জিনটি কনস্ট্রাক্টরের সঞ্চালনের সময় এখনও শূন্য থাকে, ফলে নালপয়েন্টার এক্সেকশন হয় ception

এই সমস্যাটি জাভা কনস্ট্রাক্টর ইনজেকশনের জন্য জেএসআর -330 নির্ভরতা ইনজেকশন বা জাভা @ পোষ্টকন্সট্রাক্ট পদ্ধতির টীকাটির জন্য জেএসআর 250 সাধারণ টীকা দ্বারা সমাধান করা যেতে পারে ।

@PostConstruct

জেএসআর-250 250 একটি সাধারণ টীকা নির্ধারণ করে যা জাভা এসই 6 এ অন্তর্ভুক্ত করা হয়েছে।

পোস্টকন্সট্রাক্ট টীকাগুলি কোনও পদ্ধতিতে ব্যবহৃত হয় যে কোনও প্রারম্ভিকতা সম্পাদন করার জন্য নির্ভরতা ইনজেকশন করার পরে কার্যকর করা দরকার। এই পদ্ধতিটি ক্লাসটিকে পরিষেবাতে দেওয়ার আগে ডাকা উচিত। এই টীকাটি এমন সমস্ত শ্রেণিতে সমর্থন করা উচিত যা নির্ভরতা ইনজেকশন সমর্থন করে।

জেএসআর -250 চ্যাপ। 2.5 জাভ্যাক্স.অনোটেশন.পোস্টকনস্ট্রাক্ট

@ পোষ্টকন্সট্রাক্ট টিকাটি উদাহরণটি ইনস্ট্যান্ট হয়ে যাওয়ার পরে এবং সমস্ত ইনজেকশন সঞ্চালনের পরে পদ্ধতির সংজ্ঞা কার্যকর করার অনুমতি দেয়।

public class Car {
  @Inject
  private Engine engine;  

  @PostConstruct
  public void postConstruct() {
    engine.initialize();  
  }
  ...
} 

কনস্ট্রাক্টরের সূচনাটি পরিবর্তনের পরিবর্তে কোডটি @ পোষ্টকনস্ট্রাক্ট দ্বারা টীকাযুক্ত পদ্ধতিতে সরানো হয়েছে।

পোস্ট-কনস্ট্রাক্ট পদ্ধতিগুলির প্রক্রিয়াজাতকরণ হ'ল @ পোস্টকন্সট্রাক্ট দ্বারা টীকাযুক্ত সমস্ত পদ্ধতি সন্ধান করা এবং ঘুরেফিরে তাদের অনুরোধ করা সহজ বিষয়।

private  void processPostConstruct(Class type, T targetInstance) {
  Method[] declaredMethods = type.getDeclaredMethods();

  Arrays.stream(declaredMethods)
      .filter(method -> method.getAnnotation(PostConstruct.class) != null) 
      .forEach(postConstructMethod -> {
         try {
           postConstructMethod.setAccessible(true);
           postConstructMethod.invoke(targetInstance, new Object[]{});
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {      
          throw new RuntimeException(ex);
        }
      });
}

ইনস্ট্যান্টেশন এবং ইনজেকশন শেষ হওয়ার পরে পোস্ট-কনস্ট্রাক্ট পদ্ধতিগুলির প্রক্রিয়াজাতকরণ করতে হবে।


1

এছাড়াও যখনই কোনও ধরণের প্রক্সিং বা রিমোটিং জড়িত থাকে তখন নির্ধারক ভিত্তিক সূচনাটি যেমন ইচ্ছা তেমন কাজ করে না।

যখনই কোনও ইজেবি ডিজিরিয়ালে পরিণত হয় তখন সিটি কল হবে এবং যখনই এর জন্য একটি নতুন প্রক্সি তৈরি হবে ...

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