ہیلو! جبکہ JavaRush انتظامیہ نئی سطحوں پر کام کر رہی ہے، میں بہار کے فریم ورک پر تربیتی مضامین کا ایک سلسلہ شروع کرنا چاہتا ہوں۔ جی ہاں، میں جانتا ہوں کہ انٹرنیٹ پر اس موضوع پر پہلے سے ہی کافی مواد موجود ہے، لیکن جیسا کہ پریکٹس سے پتہ چلتا ہے، وہ سب ہیلو ورلڈ کی سطح پر ہیں۔ میں اس بارے میں بات نہیں کرنا چاہتا ہوں کہ تشریحات کو صحیح طریقے سے کیسے رکھا جائے، بلکہ اس بارے میں بات کرنا چاہتا ہوں کہ یہ سب کیسے کام کرتا ہے "ہڈ کے نیچے"۔ مضمون کا مقصد ان لوگوں کے لیے ہے جو پہلے ہی کسی نہ کسی طریقے سے اس فریم ورک کے ساتھ کام کر چکے ہیں اور بنیادی تصورات سے واقف ہیں۔
سیاق و سباق کو شروع کرنا۔
تو آئیے بنیادی باتوں سے شروعات کریں۔ میری رائے میں، سب سے اہم نکات میں سے ایک یہ سمجھنا ہے کہ سیاق و سباق کو کس طرح ترتیب دیا جاتا ہے اور پھلیاں شروع کی جاتی ہیں۔ جیسا کہ آپ جانتے ہیں، بہار کے کام شروع کرنے سے پہلے، اسے ترتیب دینے کی ضرورت ہے۔ قبل از وقت، یہ ایکس ایم ایل فائلوں کا استعمال کرتے ہوئے کیا جاتا تھا (کچھ پروجیکٹس پر، خاص طور پر پرانے پر، وہ آج تک ایسا کرتے رہتے ہیں)۔ اس طرح کی کنفیگریشن فائل کی ایک چھوٹی سی مثال یہ ہے:<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="helloWorld" class="ru.javarush.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
</beans>
بڑے پیمانے پر، یہ کچھ کنٹرولرز بنانے اور ایک سٹارٹ اپ شروع کرنے کے لیے کافی ہے (جو شروع نہیں ہوگا)۔ لیکن یہ ترتیب بہار کو کیسے کام کرے گی؟ اور یہاں ہے جہاں چیزیں دلچسپ ہوجاتی ہیں۔ ہماری ترتیب کو بہار کے ذریعے سمجھنے کے لیے، وہاں ایک ہے XmlBeanDefinitionReader
۔ BeanDefinition
یہ بہار کا ایک اندرونی جزو ہے جو xml کو اسکین کرتا ہے اور جو کچھ ہم نے وہاں لکھا ہے اس کی بنیاد پر تخلیق کرتا ہے۔ BeanDefinition
ایک ایسی چیز ہے جو بین کے بارے میں معلومات ذخیرہ کرتی ہے۔ اس میں شامل ہے: اسے کس طبقے سے بنایا جائے؛ دائرہ کار آیا سست ابتداء انسٹال ہے؛ کیا اس بین سے پہلے شروع کرنا ضروری ہے اور دوسری خصوصیات جو xml میں بیان کی گئی ہیں؟ تمام موصول ہونے والے BeanDefinition
کو شامل کر دیا گیا ہے HashMap
، جس میں شناخت کنندہ بین کا نام ہے (آپ کے ذریعہ مقرر کیا گیا ہے یا اسپرنگ کے ذریعہ تفویض کیا گیا ہے) اور BeanDefinition
خود آبجیکٹ۔ سب کچھ BeanDefinition
بننے کے بعد، اسٹیج پر ایک نیا ہیرو نمودار ہوتا ہے BeanFactory
۔ یہ آبجیکٹ HashMap’e
s پر اعادہ کرتا ہے BeanDefinition
، ان کی بنیاد پر پھلیاں بناتا ہے اور انہیں IoC کنٹینر میں رکھتا ہے۔ یہاں ایک نزاکت ہے، درحقیقت، جب ایپلیکیشن شروع ہوتی ہے، IoC کنٹینر میں ایسی پھلیاں ہوں گی جن کا سنگلٹن اسکوپ ہوتا ہے (بذریعہ ڈیفالٹ سیٹ)، جب کہ باقی ضرورت کے وقت بنائے جاتے ہیں (پروٹو ٹائپ، درخواست، سیشن)۔ اور اب ایک چھوٹا سا اختلاف، آئیے ایک اور کردار سے واقف ہوں۔
بین پوسٹ پروسیسر سے ملیں۔ (بی پی پی)
حقیقت یہ ہے کہ بین ضروری نہیں کہ آپ کی درخواست کے لیے کاروباری منطق کی کلاس ہو۔ ایک بین کو انفراسٹرکچر بین بھی کہا جاتا ہے۔ مختصراً، انفراسٹرکچر بین ایک ایسی کلاس ہے جو آپ کے کاروباری منطق کی پھلیاں (جی ہاں، بہت زیادہ پھلیاں) تشکیل دیتی ہے۔ میں ذیل میں آپ کو اس کے بارے میں مزید بتاؤں گا، لیکن یہ تھوڑا واضح کرنے کے لیے کہ BPP بالکل کیا ترتیب دیتا ہے، میں ایک مثال دوں گا۔ کیا ہر کوئی خلاصہ سے واقف ہے@Autowired
؟ لہذا، آپ AutowiredAnnotationBeanPostProcessor
اس بات کو یقینی بنانے کے ذمہ دار ہیں کہ آپ کی تمام کلاسیں ایک دوسرے میں سرایت کر گئی ہیں۔
آئیے BeanFactory پر واپس چلتے ہیں۔
بی پی پی کے بارے میں اب جاننے کے بعد، یہ واضح کرنا ضروری ہے کہ جبHashMap
's' پر تکرار کرتے ہیں، BeanDefinition
تو سب پہلے بنائے جاتے ہیں اور الگ الگ رکھے جاتے ہیں (IoC کنٹینر میں نہیں) BeanPostProcessor
۔ اس کے بعد، ہماری کاروباری منطق کی باقاعدہ پھلیاں بنائی جاتی ہیں، ایک IoC کنٹینر میں ڈالی جاتی ہیں، اور ان کی ترتیب الگ سے موخر شدہ BPPs کا استعمال کرتے ہوئے شروع ہوتی ہے۔ اور یہ اس طرح ہوتا ہے، ہر BPP کے 2 طریقے ہیں:
postProcessorBeforeInitialization(Object bean, String beanName);
postProcessorAfterInitialization(Object bean, String beanName);
ہمارے ڈبوں کے ذریعے دو بار اعادہ ہوتا ہے۔ پہلی بار طریقہ کہا جاتا ہے postProcessorBeforeInitialization
، اور دوسری بار طریقہ کہا جاتا ہے postProcessorAfterInitialization
. یقیناً یہ سوال پیدا ہوا ہے کہ دو طریقوں کی ضرورت کیوں ہے، میں وضاحت کرتا ہوں۔ حقیقت یہ ہے کہ کچھ تشریحات پر کارروائی کرنے کے لیے (جیسے @Transactional
، مثال کے طور پر)، ہماری بین کو پراکسی کلاس سے بدل دیا جاتا ہے۔ یہ سمجھنے کے لیے کہ ایسا کیوں ہوتا ہے، آپ کو یہ جاننا ہوگا کہ یہ کیسے کام کرتا ہے @Transactional
، اور یہ اس طرح کام کرتا ہے۔ آپ کو فلائی پر اس تشریح کے ساتھ نشان زد طریقہ میں کوڈ کی کچھ مزید لائنیں شامل کرنے کی ضرورت ہے۔ یہ کیسے کرنا ہے؟ یہ ٹھیک ہے، ایک پراکسی کلاس بنا کر، جس کے اندر ضروری کوڈ کو مطلوبہ طریقہ میں شامل کر دیا جائے گا۔ اب اس صورتحال کا تصور کریں، ہمارے پاس ایک کلاس ہے:
class A {
@Autowired
private SomeClass someClass;
@Transactional
public void method() {
// модификатор доступа обязательно public
}
}
اس کلاس میں 2 تشریحات ہیں @Autowired
اور @Transactional
. دونوں تشریحات پر مختلف BPPs کے ذریعے کارروائی کی جاتی ہے۔ اگر یہ سب سے پہلے کام کرتا ہے AutowiredBPP
، تو سب کچھ ٹھیک ہو جائے گا، لیکن اگر نہیں، تو ہم اس مسئلہ کا سامنا کریں گے. حقیقت یہ ہے کہ جب پراکسی کلاس بنائی جاتی ہے تو تمام میٹا معلومات ضائع ہوجاتی ہیں۔ @Autowired
دوسرے لفظوں میں، پراکسی کلاس میں تشریح کے بارے میں کوئی معلومات نہیں ہوگی ، اور اس وجہ سے AutowiredBPP
یہ کام نہیں کرے گا، جس کا مطلب ہے کہ ہمارے فیلڈ میں someClass
قدر ہوگی null
، جو ممکنہ طور پر NPE کی طرف لے جائے گی۔ یہ بھی جاننے کے قابل ہے کہ میتھڈ کالز کے درمیان، -میتھڈ کہا جاتا postProcessorBeforeInitialization
ہے ، اگر کوئی ہے۔ یہ بنیادی طور پر دوسرا کنسٹرکٹر ہے، لیکن فرق یہ ہے کہ اس وقت ہمارے تمام انحصار کلاس میں پہلے سے ہی سرایت کر چکے ہیں اور ہم ان تک رسائی حاصل کر سکتے ہیں ۔ لہذا، ایک بار پھر سیاق و سباق کی ابتداء الگورتھم: postProcessorAfterInitialization
init
init
XmlBeanDefinitionReader
ہماری xML کنفیگریشن فائل کو اسکین کرتا ہے۔- کی تخلیق کرتا ہے
BeanDefinition
اور ڈالتا ہےHashMap
۔ - آتا ہے
BeanFactory
اور اس سے الگ الگ تمام 's کوHashMap
جوڑتا ہے ۔BeanPostProcessor
BeanDefinition
سے پھلیاں بناتا ہے اور انہیں IoC کنٹینر میں رکھتا ہے۔- یہاں BPPs آتے ہیں اور 2 طریقوں سے ان پھلیوں کو ترتیب دیتے ہیں۔
- تیار.
GO TO FULL VERSION