স্প্রিং @ অটোভায়ার্ড ব্যবহার বোঝা যাচ্ছে


309

স্প্রিং অটোওয়ার্ড এন্টারোটেশন বুঝতে আমি বসন্ত 3.0.০.x রেফারেন্স ডকুমেন্টেশন পড়ছি:

৩.৯.২ @ অটোভায়ার্ড এবং @ ইনজেক্ট

আমি নীচের উদাহরণগুলি বুঝতে সক্ষম নই। এটি কাজ করার জন্য আমাদের কি এক্সএমএল কিছু করার প্রয়োজন?

উদাহরণ 1

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

উদাহরণ 2

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(MovieCatalog movieCatalog,
                    CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

কীভাবে দুটি শ্রেণি একই ইন্টারফেস প্রয়োগ করে এবং একই বর্গ ব্যবহার করে স্বশক্ত হতে পারে?

উদাহরণ:

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

    draw(){
        color.design(); 
    } 
}

কোন ডিজাইনের পদ্ধতি বলা হবে? আমি কীভাবে নিশ্চিত করব যে রেড ক্লাসের ডিজাইন পদ্ধতিটি নীল নয় এবং বলা হবে?

উত্তর:


542

টি এল; ডিআর

@ অটোভায়ার্ড টীকাগুলি আপনাকে এক্সএমএল ফাইল (বা অন্য কোনও উপায়ে) থেকে নিজের দ্বারা ওয়্যারিংয়ের প্রয়োজনীয়তা বাঁচায় এবং কোথায় আপনাকে ইঞ্জেকশন দেওয়ার দরকার তা খুঁজে পেয়েছে এবং এটি আপনার জন্য কী করে।

সম্পূর্ণ ব্যাখ্যা

@Autowiredটীকা কি আপনি উদ্বুদ্ধ করতে এর অন্যত্র কনফিগারেশনের এড়িয়ে যেতে দেয় এবং শুধুমাত্র আপনার জন্য এটা আছে। আপনার প্যাকেজটি ধরে নিচ্ছেন যে com.mycompany.moviesআপনি এই ট্যাগটি আপনার এক্সএমএল (অ্যাপ্লিকেশন প্রসঙ্গে ফাইল) রাখতে হবে:

<context:component-scan base-package="com.mycompany.movies" />

এই ট্যাগটি একটি অটো-স্ক্যানিং করবে। ধরে নেওয়া যায় যে প্রতিটি শ্রেণি যা শিম হয়ে উঠতে হবে একটি সঠিক টীকা যেমন @Component(সাধারণ শিমের জন্য) বা @Controller(একটি সার্লেট নিয়ন্ত্রণের জন্য) বা @Repository( DAOক্লাসগুলির জন্য ) এবং এই ক্লাসগুলি প্যাকেজের অধীনে কোথাও রয়েছে com.mycompany.movies, স্প্রিং এই সমস্তটি সন্ধান করবে এবং তৈরি করবে প্রতিটি জন্য একটি শিম। এটি 2 টি ক্লাসের স্ক্যানে করা হয় - প্রথমবার এটি কেবল ক্লাসগুলির সন্ধান করে যা সিম হতে হবে এবং এটি করার জন্য যে ইঞ্জেকশনগুলি লাগানোর দরকার তা ম্যাপ করে এবং দ্বিতীয় স্ক্যানে এটি মটরশুটিগুলিকে ইনজেকশন দেয়। অবশ্যই, আপনি আপনার মটরশুটিটিকে আরও বেশি traditional তিহ্যবাহী এক্সএমএল ফাইলে বা একটি @ কনফিগারেশন ক্লাস (বা তিনটির কোনও সমন্বয়) দিয়ে সংজ্ঞায়িত করতে পারেন ।

@Autowiredটীকা স্প্রিং বলে যেখানে একটি ইনজেকশন ঘটতে হবে। যদি আপনি এটি এমন কোনও পদ্ধতিতে রাখেন তবে setMovieFinderএটি বুঝতে পারে (উপসর্গ set+ @Autowiredটিকা দ্বারা) যে শিমটি ইনজেকশন দেওয়া দরকার। দ্বিতীয় স্ক্যানে, স্প্রিং প্রজাতির MovieFinderশিমের সন্ধান করে এবং যদি এটি এর মতো শিমটি খুঁজে পায় তবে এটি এটিকে এই পদ্ধতিতে সংক্রামিত করে। যদি এটি দুটি এর মতো মটরশুটি খুঁজে পায় আপনি একটি পাবেন Exception। এড়াতে Exception, আপনি @Qualifierটীকাটি ব্যবহার করতে পারেন এবং দুটি শিমের মধ্যে কোনটি নিম্নলিখিত পদ্ধতিতে ইনজেক্ট করতে হবে তা বলতে পারেন:

@Qualifier("redBean")
class Red implements Color {
   // Class code here
}

@Qualifier("blueBean")
class Blue implements Color {
   // Class code here
}

অথবা আপনি যদি আপনার এক্সএমএলে মটরশুটি ঘোষনা করতে পছন্দ করেন তবে এটি দেখতে এমন কিছু দেখাচ্ছে:

<bean id="redBean" class="com.mycompany.movies.Red"/>

<bean id="blueBean" class="com.mycompany.movies.Blue"/>

ইন @Autowiredঘোষণা, এছাড়াও আপনি যোগ করতে হবে @Qualifierযা দুই রঙ মটরশুটি উদ্বুদ্ধ করতে বোলো না;

@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
  this.color = color;
}

আপনি যদি দুটি টিকা ব্যবহার করতে না চান ( @Autowiredএবং @Qualifier) আপনি @Resourceএই দুটি একত্রিত করতে ব্যবহার করতে পারেন :

@Resource(name="redBean")
public void setColor(Color color) {
  this.color = color;
}

@Resource(আপনি যদি এই উত্তরে প্রথম মন্তব্য তা সম্পর্কে কিছু অতিরিক্ত ডেটা পড়তে পারে) আপনি দুই টীকা ব্যবহার spares এবং এর পরিবর্তে আপনি যদি শুধুমাত্র একটি ব্যবহার করুন।

আমি আরও দুটি মন্তব্য যুক্ত করব:

  1. এর @Injectপরিবর্তে ভাল অনুশীলনটি ব্যবহার করা হবে @Autowiredকারণ এটি স্প্রিং-নির্দিষ্ট নয় এবং এটি JSR-330স্ট্যান্ডার্ডের অংশ
  2. আরেকটি ভাল অনুশীলন হ'ল পদ্ধতির পরিবর্তে কনস্ট্রাক্টরের উপর @Inject/ রাখা @Autowired। আপনি যদি এটি কোনও কনস্ট্রাক্টরের উপর রাখেন তবে আপনি যাচাই করতে পারেন যে ইনজেকশন করা মটরশুটিগুলি শালীন নয় এবং দ্রুত ব্যর্থ হয় যখন আপনি অ্যাপ্লিকেশনটি শুরু করার চেষ্টা করেন এবং NullPointerExceptionযখন আপনাকে আসলে শিমটি ব্যবহার করার দরকার হয় তখন এড়ানো উচিত।

আপডেট : ছবিটি সম্পূর্ণ করতে, আমি ক্লাস সম্পর্কে একটি নতুন প্রশ্ন তৈরি করেছি @Configuration


6
আপনার দুর্দান্ত উত্তরটি সম্পূর্ণ করার জন্য: '@ রিসোর্স' জেএসআর -২০০০ স্ট্যান্ডার্ডের একটি অংশ এবং সাধারণ ইনজেকশনটির উপরে এবং উপরে অতিরিক্ত শব্দার্থবিজ্ঞান রয়েছে (যেমন আপনি বলেছেন যে '@ অটোভায়ার্ড' স্প্রিংয়ের; এবং '@ ইনজেক্ট' একটি অংশ) জেএসআর -330) :)
ইগনাসিও রুবিও

যদি MovieFinderএকটি ইন্টারফেস হয়, এবং আমাদের MovieFinderImpl(বিন আইডি = মুভিফাইন্ডার) এর জন্য বিন রয়েছে, স্প্রিং এটিকে স্বয়ংক্রিয়ভাবে টাইপ করে বা নাম দিয়ে দেবে?
জেসকি

@ জাসকি - এটি আপনি ব্যবহার করছেন কিনা তার উপর নির্ভর করে @Qualifier। আপনি যদি নাম দিয়ে থাকেন, তবে না - টাইপ করে। MovieFinderআপনার প্রসঙ্গে যদি কেবলমাত্র একটি বিন বিন টাইপ করা হয় তবে কেবলমাত্র টাইপটি কাজ করবে । 1 এর বেশি একটি ব্যতিক্রম হতে পারে।
আভি

@ অভি, দুর্দান্ত উত্তর তবে উদাহরণ 2-@Autowiredprepareপদ্ধতিটিতে টিকা কীভাবে কাজ করে তা আমি বুঝতে পারি না । এটি প্রযুক্তিগত দিক থেকে এটি সূচনা করছে তবে এটি কোনও সেটটার নয়MovieRecommender
করণ চাদা

@ করণচাদা - @Autowiredএটি নির্মাণকারীদের জন্যও কাজ করে। এটি প্রয়োজনীয় নির্ভরতাগুলি সন্ধান করে এবং তাদেরকে নির্মাণকারীর সাথে সংযুক্ত করে।
আভি

21

উদাহরণের কিছুই বলে না যে "ক্লাসগুলি একই ইন্টারফেস প্রয়োগ করছে"। MovieCatalogএকটি টাইপ এবং CustomerPreferenceDaoঅন্য ধরনের। বসন্ত তাদের সহজেই আলাদা করে বলতে পারে।

স্প্রিং ২.x এ সিমের ওয়্যারিং বেশিরভাগ শিমের আইডি বা নামগুলির মাধ্যমে ঘটে। এটি এখনও স্প্রিং 3.x দ্বারা সমর্থিত তবে প্রায়শই আপনার কাছে একটি নির্দিষ্ট ধরণের শিমের একটি উদাহরণ থাকবে - বেশিরভাগ পরিষেবাদি সিঙ্গেলটন। তাদের জন্য নাম তৈরি করা ক্লান্তিকর। সুতরাং স্প্রিং "টাইপ করে স্বতন্ত্রকরণ" সমর্থন করা শুরু করে।

উদাহরণগুলি কী দেখায় তা হ'ল বিভিন্ন উপায়ে আপনি ক্ষেত্র, পদ্ধতি এবং নির্মাতাদের সিম ইনজেকশন করতে ব্যবহার করতে পারেন।

এক্সএমএলটিতে স্প্রিংয়ের প্রয়োজনীয় সমস্ত তথ্য ইতিমধ্যে রয়েছে যেহেতু আপনাকে প্রতিটি বিনের পুরোপুরি যোগ্যতাসম্পন্ন শ্রেণীর নাম উল্লেখ করতে হবে। ইন্টারফেসগুলির সাথে আপনাকে কিছুটা সতর্ক হওয়া দরকার, যদিও:

এই অটোয়ারিং ব্যর্থ হবে:

 @Autowired
 public void prepare( Interface1 bean1, Interface1 bean2 ) { ... }

জাভা যেহেতু প্যারামিটারের নামগুলি বাইট কোডে রাখে না, তাই স্প্রিং দুটি শিমের মধ্যে আর পার্থক্য করতে পারে না। সমাধানটি ব্যবহার করতে হবে @Qualifier:

 @Autowired
 public void prepare( @Qualifier("bean1") Interface1 bean1,
     @Qualifier("bean2")  Interface1 bean2 ) { ... }

পছন্দ করেছেন তবে আমি জানতে চাই আপনি কীভাবে ফাংশনটি কল করবেন prepare, কোন পরামিতি এই ফাংশনটি কল করতে ব্যবহৃত হবে?
এনগুইন কোয়াং আন

@ এনগুইনকুয়াংএইচ আমি পদ্ধতিটি কল করছি না, শিমটি তৈরি হওয়ার পরে বসন্ত এটি করবে। @Autowiredক্ষেত্রগুলি ইনজেকশনের সময় ঠিক এটি ঘটে । বসন্ত তারপরে দেখবে যে প্যারামিটারগুলি প্রয়োজন এবং এটি পরামিতিগুলি খুঁজতে ক্ষেত্রের ইনজেকশনের জন্য ব্যবহৃত একই নিয়ম ব্যবহার করবে।
অ্যারন দিগুল্লা 4'17

5

হ্যাঁ, আপনি আপনার মটরশুটি (অর্থাত্ ক্লাস) সংজ্ঞায়িত করতে স্প্রিং সার্লেট প্রসঙ্গ xML ফাইলটি কনফিগার করতে পারেন, যাতে এটি আপনার জন্য স্বয়ংক্রিয় ইনজেকশনটি করতে পারে। তবে নোট করুন, স্প্রিং আপ এবং চলমান রাখতে আপনাকে অন্যান্য কনফিগারেশন করতে হবে এবং এটি করার সর্বোত্তম উপায়টি হল টিউটোরিয়াল ভিত্তি অনুসরণ করা।

আপনার বসন্তটি সম্ভবত কনফিগার হয়ে গেলে আপনি উপরের উদাহরণ 1 এর জন্য আপনার স্প্রিং সার্লেট প্রসঙ্গ xML ফাইলটিতে নিম্নলিখিতটি করতে পারেন (দয়া করে com.movies এর প্যাকেজের নামটি সত্য প্যাকেজের নাম কী এবং যদি এটি তৃতীয় পক্ষ হয় তবে প্রতিস্থাপন করুন ক্লাস, তারপরে নিশ্চিত হয়ে নিন যে উপযুক্ত জার ফাইলটি ক্লাসপথে রয়েছে):

<beans:bean id="movieFinder" class="com.movies.MovieFinder" />

অথবা মুভিফাইন্ডার ক্লাসে যদি কোনও প্রাথমিক মান সহ কোনও নির্মাণকারী থাকে তবে আপনি এরকম কিছু করতে পারেন,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg value="100" />
</beans:bean>

অথবা যদি মুভিফাইন্ডার ক্লাসে কোনও নির্মাণকারীর কাছে অন্য শ্রেণীর প্রত্যাশা থাকে তবে আপনি এরকম কিছু করতে পারেন,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg ref="otherBeanRef" />
</beans:bean>

... যেখানে ' অন্যান্যবিয়ানআরফ ' হ'ল আরেকটি শিম যা প্রত্যাশিত শ্রেণির রেফারেন্স রাখে।


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