سی ڈی آئی کے ساتھ کوارکس میں انحصار کا انجکشن: آر سی، اسکوپس، کوالیفائرز اور بلڈ ٹائم انجیکشن
Dependency Injection (DI) جدید انٹرپرائز جاوا ایپلیکیشن کی ترقی کی بنیاد ہے۔ برسوں سے، جاوا کے ڈویلپرز نے اسپرنگ IoC (Inversion of Control) یا معیاری Jakarta EE CDI (Contexts and Dependency Injection) کنٹینرز جیسے Hibernate Weld یا OpenWebBeans پر انحصار کیا تاکہ اجزاء کی لائف سائیکل کو ڈیکپل کرنے، سروس کے انحصار کو منظم کرنے اور کنفیگریشن پراپرٹیز کو انجیکشن کرنے کے لیے۔
تاہم، جیسا کہ انٹرپرائز ایپلی کیشنز کلاؤڈ مقامی مائیکرو سروسز کی طرف منتقل ہوئیں، Docker اور Kubernetes کے ساتھ کنٹینرائزیشن، اور سرور لیس ایگزیکیوشن ماڈلز (AWS Lambda، Knative)، روایتی انحصار انجیکشن کنٹینرز نے ایک اہم خامی کو بے نقاب کیا: بھاری رن ٹائم عکاسی اور زیادہ میموری**۔
Quarkus اور اس کا ہلکا پھلکا CDI انجن، ArC درج کریں۔ Kubernetes اور GraalVM مقامی تالیف کے لیے گراؤنڈ اپ سے بنایا گیا، Quarkus ریفیکشن، کلاس پاتھ اسکیننگ، اور ایپلیکیشن رن ٹائم سے بین گراف وائرنگ کو وقت کی تعمیر کے لیے شفٹ کرکے انحصار کے انجیکشن کی نئی تعریف کرتا ہے۔
اس گہرے غوطے کی گائیڈ میں، ہم **CDI کے ساتھ Quarkus میں Dependency Injection کا جائزہ لیں گے، جس میں ArC کنٹینر، CDI اسکوپس، کسٹم کوالیفائرز، پروڈیوسرز، انٹرسیپٹرز، ایونٹ سے چلنے والے مبصرین، پروگرامیٹک تلاش، اور اعلی کارکردگی والے جاوا ایپلیکیشن کلاؤڈ-لکھنے کے بہترین طریقوں کا احاطہ کیا جائے گا۔
1. ArC کو سمجھنا: Quarkus Build-Time CDI انجن
معیاری جکارتہ EE CDI کنٹینرز ایپلی کیشن کے آغاز پر مکمل طور پر کام کرتے ہیں۔ جب کوئی لیگیسی ایپلیکیشن بوٹ ہوتی ہے، تو CDI کنٹینر کلاس پاتھ میں ہر JAR کو اسکین کرتا ہے، میٹا ڈیٹا کو پارس کرتا ہے، جاوا ریفلیکشن (java.lang.reflect) کا استعمال کرتے ہوئے تشریحات کا معائنہ کرتا ہے، میموری میں متحرک پراکسیز تیار کرتا ہے، اور انحصار کا گراف بناتا ہے۔ یہ متحرک عکاسی اہم RAM (میٹا اسپیس) استعمال کرتی ہے اور کولڈ اسٹارٹ بوٹ ٹائم کو بڑھاتی ہے۔
Quarkus اس رکاوٹ کو ArC (جکارتہ CDI 4.0 تصریحات پر مبنی بلٹ ٹائم CDI نفاذ) کے ساتھ حل کرتا ہے۔
ArC معیاری CDI سے کس طرح مختلف ہے:
- تعمیر کے وقت میں اضافہ:
mvn packageیا./gradlew buildکے دوران، ArC تمام ایپلیکیشن بینز کو اسکین کرتا ہے، انجیکشن پوائنٹس کی توثیق کرتا ہے، اور انحصاری گراف کو پہلے سے بناتا ہے۔ - Ahead-Of-Time (AOT) بائیک کوڈ جنریشن: ARC انسٹینٹیشن، بین پراکسیز، اور انٹرسیپٹرز کے لیے براہ راست جاوا بائیک کوڈ تیار کرتا ہے، رن ٹائم پر عکاسی کو ختم کرتا ہے۔
- غیر استعمال شدہ بین کی کٹائی (ڈیڈ کوڈ کا خاتمہ): کوئی بھی سی ڈی آئی بین جو کبھی بھی انجیکشن یا متحرک طور پر حوالہ نہیں دیا جاتا ہے اس کی شناخت تالیف کے دوران کی جاتی ہے اور خود بخود حتمی بائنری سے چھین لی جاتی ہے، جس سے میموری فوٹ پرنٹ کو کم کیا جاتا ہے۔
- GraalVM Native Image Optimization: چونکہ بین وائرنگ کو تعمیراتی وقت پر حل کیا جاتا ہے، Quarkus ایپلی کیشنز صفر ریفلیکشن کنفیگریشن اشارے کے ساتھ مقامی ایگزیکیوٹیبلز میں بغیر کسی رکاوٹ کے مرتب کرتی ہیں۔
2. CDI بین اسکوپس اور لائف سائیکل مینجمنٹ
CDI میں، ایک Scope ایک بین مثال کے لائف سائیکل اور مرئیت کا حکم دیتا ہے۔ Quarkus ArC تعمیراتی وقت کی اصلاح کے ساتھ معیاری جکارتہ CDI اسکوپس کو سپورٹ کرتا ہے۔
کوارکس میں بنیادی CDI اسکوپس:
| دائرہ کار تشریح | لائف سائیکل اور برتاؤ | پراکسی تخلیق | بہترین استعمال کا کیس |
|---|---|---|---|
@ApplicationScoped |
فی درخواست واحد مثال۔ پہلی درخواست پر سست آغاز۔ ریاست تمام دھاگوں میں مشترکہ ہے۔ | کلائنٹ پراکسی تیار کی گئی۔ | اسٹیٹ لیس سروسز، ریپوزٹریز، کنفیگریشنز۔ |
@RequestScoped |
مثال ایک ہی HTTP درخواست یا ایونٹ کی درخواست کے پابند ہے۔ درخواست مکمل ہونے پر تباہ کر دیا گیا۔ | کلائنٹ پراکسی تیار کی گئی۔ | صارف کے سیشنز، سیاق و سباق کے ڈیٹا کی درخواست کریں، سیکیورٹی ٹوکنز۔ |
@Dependent |
پہلے سے طے شدہ دائرہ کار اگر کوئی متعین نہ ہو۔ مثال براہ راست انجیکشن بین کی زندگی بھر سے منسلک ہے۔ | کوئی پراکسی نہیں (براہ راست مثال) | مددگار یوٹیلیٹی کلاسز، عارضی ریاست کے حاملین۔ |
@ سنگلٹن |
فی درخواست واحد مثال۔ بے تابی سے یا سستی سے فوری۔ کوئی کلائنٹ پراکسی ریپر نہیں۔ | کوئی پراکسی نہیں (براہ راست مثال) | اعلی کارکردگی والے سنگل ٹن جہاں کلائنٹ پراکسی اوور ہیڈ سے گریز کرنا چاہیے۔ |
@Unremovable |
مارکر تشریح آر سی کو ہدایت کرتی ہے کہ بلڈ ٹائم آپٹیمائزیشن کے دوران بین کو نہ ہٹائے۔ | دائرہ کار پر منحصر ہے۔ | متحرک تلاش کے اہداف یا عکاسی کے حوالے سے پھلیاں۔ |
کوڈ کی مثال: اسکوپڈ بینز کا اعلان کرنا
package com.ghaznix.services;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.RequestScoped;
import java.util.UUID;
@ApplicationScoped
public class OrderProcessingService {
public String processOrder(String orderId) {
return "Order " + orderId + " processed successfully.";
}
}
@RequestScoped
public class RequestContextHolder {
private final String requestId = UUID.randomUUID().toString();
public String getRequestId() {
return requestId;
}
}
3. کوارکس میں انحصار انجیکشن کے نمونے۔
Quarkus معیاری jakarta.inject.Inject تشریح کا استعمال کرتے ہوئے متعدد انجیکشن اسٹائل کو سپورٹ کرتا ہے۔
A. کنسٹرکٹر انجکشن (تجویز کردہ بہترین پریکٹس)
کنسٹرکٹر انجکشن ناقابل تغیر (final فیلڈز) کی ضمانت دیتا ہے، CDI کنٹینرز کی ضرورت کے بغیر یونٹ ٹیسٹنگ کو آسان بناتا ہے، اور انحصار کو واضح کرتا ہے۔
package com.ghaznix.resources;
import com.ghaznix.services.OrderProcessingService;
import jakarta.inject.Inject;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
@Path("/orders")
public class OrderResource {
private final OrderProcessingService orderService;
// In Quarkus, if a class has a single constructor, @Inject is OPTIONAL!
@Inject
public OrderResource(OrderProcessingService orderService) {
this.orderService = orderService;
}
@POST
@Path("/{id}")
public String checkout(@PathParam("id") String id) {
return orderService.processOrder(id);
}
}
پرو ٹپ: Quarkus ArC میں، اگر ایک بین میں صرف ایک کنسٹرکٹر ہے، تو آپ
@Injectتشریح کو مکمل طور پر چھوڑ سکتے ہیں۔ آر سی خود بخود اسے انجیکشن کنسٹرکٹر کے طور پر پہچانتا ہے۔
B. فیلڈ انجیکشن
فیلڈ انجیکشن مختصر ہے لیکن فیلڈز کو متغیر بناتا ہے اور اسٹینڈ اکیلے یونٹ ٹیسٹنگ کو پیچیدہ بناتا ہے۔
@ApplicationScoped
public class NotificationService {
@Inject
EmailClient emailClient; // Field injection
}
4. کوالیفائرز اور ایک سے زیادہ نفاذ کو واضح کرنا
جب ایک سے زیادہ پھلیاں ایک ہی انٹرفیس کو لاگو کرتی ہیں، تو CDI تعمیر کے وقت ایک مبہم انحصاری استثناء پھینک دیتا ہے۔ Quarkus ** کوالیفائرز** کا استعمال کرتا ہے تاکہ ٹارگٹ بین کے نفاذ کو محفوظ طریقے سے حل کیا جا سکے۔
کسٹم کوالیفائرز کی وضاحت کرنا
package com.ghaznix.payment;
import jakarta.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface PaymentType {
Mode value();
enum Mode {
CREDIT_CARD,
PAYPAL,
CRYPTO
}
}
کوالیفائیڈ بینز کو لاگو کرنا
public interface PaymentProcessor {
void process(double amount);
}
@ApplicationScoped
@PaymentType(PaymentType.Mode.CREDIT_CARD)
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void process(double amount) {
System.out.println("Processing Credit Card payment: $" + amount);
}
}
@ApplicationScoped
@PaymentType(PaymentType.Mode.PAYPAL)
public class PayPalProcessor implements PaymentProcessor {
@Override
public void process(double amount) {
System.out.println("Processing PayPal payment: $" + amount);
}
}
کوالیفائیڈ بینز کا انجیکشن لگانا
@ApplicationScoped
public class CheckoutService {
private final PaymentProcessor creditCardProcessor;
private final PaymentProcessor payPalProcessor;
@Inject
public CheckoutService(
@PaymentType(PaymentType.Mode.CREDIT_CARD) PaymentProcessor creditCardProcessor,
@PaymentType(PaymentType.Mode.PAYPAL) PaymentProcessor payPalProcessor) {
this.creditCardProcessor = creditCardProcessor;
this.payPalProcessor = payPalProcessor;
}
}
5. پروڈیوسر اور ڈسپوزر: تھرڈ پارٹی آبجیکٹ کو انجیکشن لگانا
بعض اوقات آپ کو فریق ثالث لائبریریوں (جیسے، AWS SDK کلائنٹس، Redis کنکشنز، کسٹم کنفیگریشن بینز) سے کلاسیں لگانے کی ضرورت ہوتی ہے جو @ApplicationScoped کے ساتھ تشریح شدہ نہیں ہیں۔ Quarkus اسے پروڈیوسر کے طریقے اور ڈسپوزر کا استعمال کرتے ہوئے ہینڈل کرتا ہے۔
package com.ghaznix.config;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@ApplicationScoped
public class DatabaseConnectionProducer {
@Produces
@ApplicationScoped
public Connection createDatabaseConnection() throws SQLException {
return DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydb", "user", "pass");
}
// Disposer method called automatically when bean is destroyed
public void closeConnection(@Disposes Connection connection) throws SQLException {
if (connection != null && !connection.isClosed()) {
connection.close();
}
}
}
6. CDI انٹرسیپٹرز: Aspect-Oriented Programming (AOP)
انٹرسیپٹرز کراس کٹنگ خدشات (لاگنگ، آڈٹ ٹریلز، میٹرکس، ریٹ لیمٹنگ) کو بغیر کاروبار کی منطق کو آلودہ کیے بین طریقوں سے منسلک کرنے کی اجازت دیتے ہیں۔
مرحلہ 1: انٹرسیپٹر بائنڈنگ کی وضاحت کریں۔
package com.ghaznix.interceptors;
import jakarta.interceptor.InterceptorBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@InterceptorBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface LogExecutionTime {
}
مرحلہ 2: انٹرسیپٹر لاجک کو نافذ کریں۔
package com.ghaznix.interceptors;
import jakarta.annotation.Priority;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
@LogExecutionTime
@Interceptor
@Priority(Interceptor.Priority.APPLICATION)
public class LogExecutionTimeInterceptor {
@AroundInvoke
public Object logInvocation(InvocationContext context) throws Exception {
long startTime = System.currentTimeMillis();
try {
return context.proceed();
} finally {
long duration = System.currentTimeMillis() - startTime;
System.out.printf("[AUDIT] Method %s executed in %d ms%n",
context.getMethod().getName(), duration);
}
}
}
مرحلہ 3: ٹارگٹ بینز کی تشریح کریں۔
@ApplicationScoped
public class AnalyticsService {
@LogExecutionTime
public void computeAggregates() {
// Business computation
}
}
چونکہ Quarkus تعمیر کے وقت جامد انٹرسیپٹر پراکسی تیار کرتا ہے، اسپرنگ بوٹ میں ڈائنامک CGLIB رن ٹائم پراکسیز کے مقابلے میں طریقہ کار کی درخواست اوور ہیڈ عملی طور پر صفر ہے۔
7. CDI ایونٹس کے ساتھ ایونٹ سے چلنے والا فن تعمیر
سی ڈی آئی بلٹ ان سنکرونس اور غیر مطابقت پذیر ایونٹ پبلشنگ فراہم کرتا ہے تاکہ ڈیکپل ان پروسیس کمیونیکیشن ہو۔
واقعات کی اشاعت اور مشاہدہ
// 1. Define Event Payload
public record OrderCreatedEvent(String orderId, double totalAmount) {}
// 2. Publish Event
@ApplicationScoped
public class OrderService {
@Inject
Event<OrderCreatedEvent> orderEventPublisher;
public void createOrder(String orderId, double amount) {
// Create order logic...
orderEventPublisher.fire(new OrderCreatedEvent(orderId, amount));
}
}
// 3. Observe Event Synchronously or Asynchronously
@ApplicationScoped
public class InventoryObserver {
public void onOrderCreated(@Observes OrderCreatedEvent event) {
System.out.println("Updating inventory for order: " + event.orderId());
}
public void onOrderCreatedAsync(@ObservesAsync OrderCreatedEvent event) {
System.out.println("Async audit log for order: " + event.orderId());
}
}
ایپلیکیشن لائف سائیکل ایونٹس
جب ایپلیکیشن لانچ یا ختم ہوتی ہے تو Quarkus ابتدائی کوڈ پر عمل کرنے کے لیے سٹارٹ اپ اور شٹ ڈاؤن ایونٹس کو ظاہر کرتا ہے:
@ApplicationScoped
public class ApplicationLifecycleBean {
void onStart(@Observes StartupEvent ev) {
System.out.println("Quarkus Application starting up...");
}
void onStop(@Observes ShutdownEvent ev) {
System.out.println("Quarkus Application shutting down...");
}
}
8. Instance<T> اور Arc.container() کے ساتھ پروگرامی بین کی تلاش
جب ہدف کے نفاذ کو رن ٹائم پر متحرک طور پر منتخب کیا جانا چاہیے (یا لیگیسی نان CDI مثالوں کے اندر)، Instance<T> یا Quarkus Arc.container() جامد تلاش کا استعمال کریں۔
@ApplicationScoped
public class DynamicPluginRegistry {
@Inject
Instance<PaymentProcessor> processors;
public void executeAll(double amount) {
for (PaymentProcessor processor : processors) {
processor.process(amount);
}
}
}
9. تعمیراتی موازنہ: Quarkus ArC بمقابلہ Spring IoC بمقابلہ ویلڈ
| فیچر | کوارکس آر سی | بہار آئی او سی کنٹینر | معیاری جکارتہ ویلڈ |
|---|---|---|---|
| انحصار کی قرارداد | تعمیر کا وقت (AOT) | رن ٹائم ریفلیکشن | رن ٹائم ریفلیکشن |
| میٹا اسپیس ریم اوور ہیڈ | انتہائی کم (~0MB میٹا ڈیٹا کے لیے) | ہائی (متحرک پراکسی کلاس کیشے) | اعتدال سے اعلیٰ |
| شروع کا وقت | ملی سیکنڈز (<0.05s) | سیکنڈز (2.5 - 8 سیکنڈ) | سیکنڈز (1.5 - 4 سیکنڈ) |
| GraalVM مقامی سپورٹ | آوٹ آف دی باکس | موسم بہار کے مقامی اشارے کی ضرورت ہے۔ | پیچیدہ ترتیب |
| غیر استعمال شدہ بین کی کٹائی | خودکار تعمیراتی وقت کی کٹائی | کلاس پاتھ میں رکھا | کلاس پاتھ میں رکھا |
| سنگل کنسٹرکٹر انجکشن | مضمر (کوئی تشریح کی ضرورت نہیں) | حمایت یافتہ | @Inject کی ضرورت ہے۔ |
10. @QuarkusTest اور @InjectMock کے ساتھ یونٹ ٹیسٹنگ CDI بینز
Quarkus JUnit 5 اور RestAssured کے ساتھ CDI بینز کی جانچ کو ہموار بناتا ہے۔ جانچ کے دوران خود بخود موکیٹو موکس کے ساتھ انحصار والی پھلیاں بدلنے کے لیے @InjectMock کا استعمال کریں۔
package com.ghaznix;
import com.ghaznix.services.OrderProcessingService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@QuarkusTest
public class OrderServiceTest {
@Inject
OrderService orderService;
@InjectMock
OrderProcessingService orderProcessingService;
@Test
public void testOrderCheckout() {
Mockito.when(orderProcessingService.processOrder("ORD-101"))
.thenReturn("Mocked Success");
String result = orderService.checkout("ORD-101");
Assertions.assertEquals("Mocked Success", result);
}
}
11۔ نتیجہ
CDI (ArC) کے ساتھ Quarkus میں Dependency Injection انٹرپرائز جاوا ڈیزائن میں ایک یادگار تبدیلی کی نشاندہی کرتا ہے۔ بین میٹا ڈیٹا اسکیننگ، پراکسی جنریشن، اور انجیکشن گراف ریزولوشن کو کمپائلیشن ٹائم میں منتقل کر کے، Quarkus سپرسونک اسٹارٹ اپ اسپیڈ، سبیاٹومک میموری فوٹ پرنٹ، اور سیملیس GraalVM مقامی بائنری سپورٹ فراہم کرتا ہے۔
چاہے آپ اسپرنگ بوٹ سے ہجرت کر رہے ہوں یا Kubernetes پر گرین فیلڈ کلاؤڈ-آبائی مائیکرو سروسز بنا رہے ہوں، Quarkus CDI میں مہارت حاصل کرنا آپ کو جدید سافٹ ویئر فن تعمیر کے لیے درکار کارکردگی اور ڈویلپر کی پیداواری صلاحیت سے لیس کرتا ہے۔
Tags
Empower Your Digital Presence & Workflows
Explore top-tier tools built by Ghaznix to streamline your links, surveys, and brand growth.