বসন্ত কীভাবে এটি সমাধান করে: শিম A শিম বি এর উপর নির্ভরশীল, এবং শিম বি-তে শিম বি B
বসন্ত কীভাবে এটি সমাধান করে: শিম A শিম বি এর উপর নির্ভরশীল, এবং শিম বি-তে শিম বি B
উত্তর:
অন্য উত্তরগুলি যেমন বলেছে, বসন্ত কেবল এটির যত্ন নেয়, শিম তৈরি করে প্রয়োজনীয় হিসাবে সেগুলি ইনজেকশন করে।
এর একটি পরিণতি হ'ল শিমের ইনজেকশন / সম্পত্তি সেটিংটি আপনার এক্সএমএল ওয়্যারিং ফাইলগুলি বোঝায় কি তার চেয়ে আলাদা ক্রমে ঘটতে পারে। সুতরাং আপনার সতর্কতা অবলম্বন করা উচিত যে আপনার সম্পত্তি সেটাররা আরম্ভ করা না করে যা ইতিমধ্যে ডেকে আনা অন্যান্য সেটারের উপর নির্ভর করে। এর সাথে ডিল করার উপায় হ'ল মটরশুটিটি InitializingBean
ইন্টারফেস বাস্তবায়ন হিসাবে ঘোষণা করা । এর জন্য আপনাকে afterPropertiesSet()
পদ্ধতিটি বাস্তবায়ন করতে হবে এবং আপনি সমালোচনামূলক সূচনাটি এখানেই করেন। (গুরুত্বপূর্ণ বৈশিষ্ট্যগুলি আসলে সেট করা হয়েছে তা যাচাই করার জন্য আমি কোডও অন্তর্ভুক্ত করি))
স্প্রিং সহায়িকা ব্যাখ্যা বিজ্ঞপ্তি নির্ভরতা মীমাংসা করা হয়। মটরশুটি প্রথমে তাত্ক্ষণিকভাবে তৈরি করা হয়, তারপরে একে অপরের মধ্যে ইনজেকশন দেওয়া হয়।
এই শ্রেণি বিবেচনা করুন:
package mypackage;
public class A {
public A() {
System.out.println("Creating instance of A");
}
private B b;
public void setB(B b) {
System.out.println("Setting property b of A instance");
this.b = b;
}
}
এবং একটি অনুরূপ বর্গ B
:
package mypackage;
public class B {
public B() {
System.out.println("Creating instance of B");
}
private A a;
public void setA(A a) {
System.out.println("Setting property a of B instance");
this.a = a;
}
}
যদি আপনার তখন এই কনফিগারেশন ফাইলটি থাকে:
<bean id="a" class="mypackage.A">
<property name="b" ref="b" />
</bean>
<bean id="b" class="mypackage.B">
<property name="a" ref="a" />
</bean>
এই কনফিগারেশনটি ব্যবহার করে একটি প্রসঙ্গ তৈরি করার সময় আপনি নিম্নলিখিত আউটপুটটি দেখতে পাবেন:
Creating instance of A
Creating instance of B
Setting property a of B instance
Setting property b of A instance
মনে রাখবেন যে যখন a
মধ্যে ইনজেকশনের হয় b
, a
এখনো পুরো ইনিশিয়ালাইজ করা হয় না।
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
কোডবেসে আমি (1 মিলিয়ন + কোডের লাইন) সাথে কাজ করছি আমাদের দীর্ঘ প্রারম্ভকালীন সময়, প্রায় 60 সেকেন্ডের মধ্যে একটি সমস্যা হয়েছিল। আমরা 12000+ ফ্যাক্টরিবিয়াননোটইনটিয়ালাইজড এক্সেকশন পেয়ে যাচ্ছিলাম ।
আমি যা করেছি তা অ্যাবস্ট্রাকবিয়ানফ্যাক্টরী # doGetBean এ শর্তযুক্ত ব্রেকপয়েন্ট স্থাপন করেছিল
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
এটি destroySingleton(beanName)
শর্তযুক্ত ব্রেকপয়েন্ট কোড সহ আমি ব্যতিক্রমটি কোথায় মুদ্রিত করেছি:
System.out.println(ex);
return false;
স্পষ্টতই এটি ঘটে যখন ফ্যাক্টরিবিয়ানগুলি একটি চক্রীয় নির্ভরতা গ্রাফের সাথে জড়িত থাকে। আমরা এপ্লিকেশনকন্টেক্সটওয়্যার বাস্তবায়ন করে এবং বিয়ান শুরু করে এবং মটরশুটি মটরশুটি ইনজেকশনের মাধ্যমে সমাধান করেছি ।
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class A implements ApplicationContextAware, InitializingBean{
private B cyclicDepenency;
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
ctx = applicationContext;
}
@Override
public void afterPropertiesSet() throws Exception {
cyclicDepenency = ctx.getBean(B.class);
}
public void useCyclicDependency()
{
cyclicDepenency.doSomething();
}
}
এটি সূচনার সময়টিকে প্রায় 15 সেকেন্ডে কেটে দেয়।
সুতরাং সবসময় ধরে নিবেন না যে আপনার জন্য এই উল্লেখগুলি সমাধান করতে বসন্ত ভাল হতে পারে good
এই কারণে আমি ভবিষ্যতের অনেক সমস্যা রোধ করার জন্য অ্যাবস্ট্রাকরফ্রেসিয়েবল অ্যাপ্লিকেশন কনটেক্সট # সেটএলসক্রাইকুলার রেফারেন্স (মিথ্যা) দিয়ে চক্রীয় নির্ভরতা রেজোলিউশনটি অক্ষম করার প্রস্তাব দিই ।
সমস্যা ->
Class A {
private final B b; // must initialize in ctor/instance block
public A(B b) { this.b = b };
}
Class B {
private final A a; // must initialize in ctor/instance block
public B(A a) { this.a = a };
}
// এর দ্বারা তৈরি: org.springframework.beans.factory.BeanCurrentlyInCreationException: 'A' নাম দিয়ে শিম তৈরিতে ত্রুটি: অনুরোধ করা শিমটি বর্তমানে তৈরিতে রয়েছে: কোনও অদলিতযোগ্য বৃত্তাকার রেফারেন্স আছে কি?
সমাধান 1 ->
Class A {
private B b;
public A( ) { };
//getter-setter for B b
}
Class B {
private A a;
public B( ) { };
//getter-setter for A a
}
সমাধান 2 ->
Class A {
private final B b; // must initialize in ctor/instance block
public A(@Lazy B b) { this.b = b };
}
Class B {
private final A a; // must initialize in ctor/instance block
public B(A a) { this.a = a };
}
এটা ঠিক এটা করে। এটি তাত্ক্ষণিকভাবে a
এবং b
, এবং একে অপরকে ইনজেক্ট করে (তাদের সেটার পদ্ধতিগুলি ব্যবহার করে)।
সমস্যা কি?
বলুন এ বি এর উপর নির্ভর করে, তারপরে স্প্রিং প্রথমে এ, তারপরে বি ইনস্ট্যান্ট করবে, তারপরে বি এর জন্য প্রোপার্টি সেট করবে, তারপরে বি কে এ এ সেট করবে Say
তবে বি যদি এ এর উপরও নির্ভর করে?
আমার উপলব্ধিটি হ'ল: বসন্তটি সবেমাত্র পাওয়া গেছে যে এ নির্মাণ করা হয়েছে (নির্বাহককে মৃত্যুদন্ড কার্যকর করা হয়েছে), তবে পুরোপুরি আরম্ভ করা হয়নি (সমস্ত ইনজেকশন সম্পন্ন করা হয়নি), ভাল, এটি ভেবেছিল, এটি ঠিক আছে, এটি সম্পূর্ণ সহনীয় যে এটিকে পুরোপুরি আরম্ভ করা হয়নি, কেবল এটি সেট করুন- আপাতত সম্পূর্ণ বি-তে এ-দের উদাহরণস্বরূপ। বি সম্পূর্ণরূপে আরম্ভ করার পরে এটি এ এ সেট করা হয়েছিল এবং শেষ পর্যন্ত এটিকে পুরোপুরি এখন আরম্ভ করা হয়েছিল।
অন্য কথায়, এটি কেবল A থেকে B কে আগাম প্রকাশ করে।
কনস্ট্রাক্টরের মাধ্যমে নির্ভরতার জন্য, স্প্রিন্টটি কেবল বিয়ানক্রেনলিআইক্রিসেশন এক্সেপশন নিক্ষেপ করুন, এই ব্যতিক্রমটি সমাধান করার জন্য, বিনের জন্য আরসের জন্য সত্যটি সেট করুন যা কনস্ট্রাক্টর-আর্গের মাধ্যমে অন্যের উপর নির্ভর করে।
থেকে বসন্ত রেফারেন্স :
সঠিকভাবে কাজ করার জন্য আপনি সাধারণত বসন্তকে বিশ্বাস করতে পারেন। এটি কনফিগারেশন সমস্যাগুলি সনাক্ত করে যেমন কনটেইনার লোড-টাইমে অস্তিত্বহীন মটরশুটি এবং বিজ্ঞপ্তি নির্ভরতাগুলির উল্লেখ। বসন্ত বৈশিষ্ট্যগুলি নির্ধারণ করে এবং যতটা সম্ভব শিমটি তৈরি করা হয় ততক্ষণে নির্ভরতাগুলি সমাধান করে।
বসন্তের ধারক সেটার-ভিত্তিক বিজ্ঞপ্তি নির্ভরতাগুলি সমাধান করতে সক্ষম তবে কনস্ট্রাক্টর-ভিত্তিক বিজ্ঞপ্তি নির্ভরতাগুলির ক্ষেত্রে একটি রানটাইম ব্যতিক্রম BeanCurrentlyInCreationException দেয়। সেটার-ভিত্তিক বিজ্ঞপ্তি নির্ভরতার ক্ষেত্রে, আইওসি কনটেইনার এটি একটি সাধারণ দৃশ্যের থেকে আলাদাভাবে পরিচালনা করে যেখানে এটি ইনজেকশনের আগে সহযোগী বিনকে সম্পূর্ণরূপে কনফিগার করে। উদাহরণস্বরূপ, শিম কলের বিন বিন এবং শিম বি এর উপর নির্ভরশীলতা থাকলে কনটেইনারটি বিতে ইনজেকশন দেওয়ার আগে সিটিকে সম্পূর্ণরূপে আরম্ভ করে এবং একবার বি পুরোপুরি শুরু করা হলে এটি এ এ ইনজেক্ট করা হয় তবে বৃত্তাকার নির্ভরতার ক্ষেত্রে, একটি মটরশুটি এর সম্পূর্ণরূপে শুরু করার আগে অন্যটিতে ইনজেকশনের ব্যবস্থা করা হয়।
আপনি যদি সাধারণত কন্সট্রাক্টর-ইঞ্জেকশন ব্যবহার করেন এবং সম্পত্তি-ইনজেকশনে স্যুইচ করতে না চান তবে স্প্রিংয়ের চেহারা -পদ্ধতি -ইনজেকশনের ফলে একটি শিমকে অন্য আলস্যভাবে তল্লাশি করতে দেওয়া হয় এবং তাই চক্র নির্ভরতা নির্ভর করে। এখানে দেখুন: http://docs.spring.io/spring/docs/1.2.9/references/beans.html#d0e1161
কনস্ট্রাক্টর ইনজেকশন ব্যর্থ হয় যখন বসন্ত শিমের মধ্যে বিজ্ঞপ্তি নির্ভরতা থাকে। সুতরাং এই ক্ষেত্রে আমরা ইনজেকশন সেটটারটি সমস্যাটি সমাধান করতে সহায়তা করে।
মূলত, কনস্ট্রাক্টর ইনজেকশন বাধ্যতামূলক নির্ভরতাগুলির জন্য দরকারী, terচ্ছিক নির্ভরতার জন্য সেটার ইঞ্জেকশন ব্যবহার করা আরও ভাল কারণ আমরা পুনরায় ইনজেকশন করতে পারি।
যদি দুটি মটরশুটি একে অপরের উপর নির্ভরশীল হয় তবে আমাদের উভয় শিমের সংজ্ঞাতে কনস্ট্রাক্টর ইঞ্জেকশন ব্যবহার করা উচিত নয়। পরিবর্তে আমাদের শিমের যে কোনও একটিতে সেটার ইঞ্জেকশন ব্যবহার করতে হবে। (অবশ্যই আমরা সেটের ইনজেকশন এন উভয় বিনের সংজ্ঞা ব্যবহার করতে পারি, তবে উভয় কনট্রাক্টর ইনজেকশনগুলি 'বিয়ানকন্ট্রালিআইক্রেশন এক্সেক্সশন' নিক্ষেপ করে)
" Https://docs.spring.io/spring/docs/current/spring-framework-references/core.html#resources-resource " এ স্প্রিং ডক রেফারেন্স করুন