Guice একটি ডিপেনডেন্সি ইনজেকশন (DI) ফ্রেমওয়ার্ক যা আপনাকে আপনার অ্যাপ্লিকেশনের বিভিন্ন উপাদানকে একে অপরের সাথে সংযুক্ত করার জন্য সহায়ক। Guice ডিফল্টভাবে Singleton এবং No Scope মডেল সরবরাহ করে, তবে আপনি যখন বিশেষ কিছু ক্ষেত্রে ডিপেনডেন্সির লাইফসাইকেল কাস্টমাইজ করতে চান, তখন Request Scope ব্যবহৃত হয়।
Request Scope প্রধানত ওয়েব অ্যাপ্লিকেশনে ব্যবহৃত হয়, যেখানে প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা ডিপেনডেন্সি তৈরি করতে হয়। Guice সাধারণত Servlet পরিবেশে Request Scope ব্যবস্থাপনার জন্য বিশেষ সমর্থন প্রদান করে।
Guice Request Scope Overview
Request Scope কিসে ব্যবহৃত হয়?
- HTTP Request Scope: একটি নির্দিষ্ট HTTP রিকোয়েস্টের মধ্যে আলাদা অবজেক্ট তৈরি করা, যাতে একই রিকোয়েস্টের মধ্যে একাধিক ক্লাসের জন্য আলাদা ইনস্ট্যান্স ব্যবহার করা যায়।
- Scoped Data: প্রতিটি HTTP রিকোয়েস্টের জন্য সেশন বা স্টেটহোল্ডার ডেটা আলাদা রাখা।
- Multithreaded Environments: যেখানে একাধিক থ্রেড একই সময়ে ডিপেনডেন্সি ব্যবহার করছে।
Guice Request Scope ব্যবহারের সুবিধা
- Isolation: প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা অবজেক্ট তৈরি হওয়ায় কোনো এক রিকোয়েস্টের ডেটা অন্য রিকোয়েস্টের সাথে মিশে না।
- Performance: এক রিকোয়েস্টের মধ্যে একবার ইনস্ট্যান্স তৈরি হলে, সেটা পরবর্তী ব্যবহারকারীর জন্য সহজে পুনঃব্যবহারযোগ্য হবে।
- Stateless Components: সার্ভারের মধ্যে স্টেটলেস কম্পোনেন্টস যেমন সার্ভিস বা রিপোজিটরিজের জন্য আলাদা স্কোপ তৈরি করা যায়।
Guice-এ Request Scope ব্যবস্থাপনা
Guice এর মধ্যে Request Scope ব্যবস্থাপনা করার জন্য Guice Servlet Module এর মতো বিশেষ প্লাগইন ব্যবহার করা হয়। এতে আপনাকে HTTP রিকোয়েস্টের জন্য ডিপেনডেন্সি স্কোপ পরিচালনা করতে সক্ষম করে।
Step 1: Guice Servlet Module ইন্সটলেশন
Guice-এর Servlet Module ব্যবহার করতে আপনাকে প্রথমে Guice-এর Guice Servlet লাইব্রেরি যুক্ত করতে হবে। Maven বা Gradle ব্যবহার করে এটি ইন্সটল করতে পারেন।
Maven Dependency:
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>5.1.0</version>
</dependency>
Gradle Dependency:
implementation 'com.google.inject.extensions:guice-servlet:5.1.0'
Step 2: RequestScope তৈরি এবং ব্যবহার
Guice-এ Request Scope ব্যবহারের জন্য আপনাকে একটি @RequestScope অ্যানোটেশন ব্যবহার করতে হবে। Guice-এ Request Scope সাধারণত GuiceServletContextListener বা GuiceServletModule ব্যবহার করে কনফিগার করা হয়।
RequestScope এর জন্য একটি ক্লাস তৈরি করুন
import com.google.inject.ScopeAnnotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ScopeAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestScope {}
এটি একটি কাস্টম @RequestScope অ্যানোটেশন যা Guice এর কনটেক্সটে Request Scope সাপোর্ট করবে।
Step 3: Guice Module কনফিগারেশন
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
public class AppModule extends AbstractModule {
@Override
protected void configure() {
// Create a binding for the service in request scope
bind(GreetingService.class).in(RequestScope.class);
}
}
এখানে, GreetingService ক্লাসটি RequestScope এ বাউন্ড করা হয়েছে, অর্থাৎ এটি HTTP রিকোয়েস্টের জন্য আলাদা একটি ইনস্ট্যান্স হবে।
Step 4: Guice Servlet Context Listener সেটআপ
import com.google.inject.servlet.GuiceServletContextListener;
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new AppModule(), new GuiceServletModule());
}
}
এখানে, GuiceServletContextListener ব্যবহার করে Guice কনটেক্সট সেটআপ করা হয়েছে এবং AppModule এবং GuiceServletModule কে কনফিগার করা হয়েছে।
Step 5: HTTP Request এ Request Scope ব্যবহার
import com.google.inject.Inject;
public class GreetingService {
private final String greetingMessage;
@Inject
public GreetingService() {
// Simulate a request-scoped service initialization
this.greetingMessage = "Hello, Guice!";
}
public String getGreetingMessage() {
return greetingMessage;
}
}
Step 6: Servlet Controller বা HTTP Request Handler
import com.google.inject.Inject;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Singleton
public class GreetingServlet extends HttpServlet {
private final GreetingService greetingService;
@Inject
public GreetingServlet(GreetingService greetingService) {
this.greetingService = greetingService;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
try {
resp.getWriter().write(greetingService.getGreetingMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}
এখানে, GreetingService ইনজেক্ট করা হয়েছে এবং HTTP রিকোয়েস্টের জন্য RequestScope ব্যবহার করা হয়েছে। প্রতিটি HTTP রিকোয়েস্টের জন্য GreetingService এর আলাদা ইনস্ট্যান্স তৈরি হবে।
Best Practices for Using Request Scope
- Use Request Scope for HTTP-Specific Resources: HTTP রিকোয়েস্ট এবং রেসপন্সের জন্য ডিপেনডেন্সি তৈরি করতে Request Scope ব্যবহার করুন।
- Avoid Memory Leaks:
RequestScopeডিপেনডেন্সি একে অপরের সাথে অপ্রয়োজনীয়ভাবে শেয়ার না হয়, এবং প্রত্যেক রিকোয়েস্টের পর অবজেক্টগুলি সঠিকভাবে পরিস্কার হয় তা নিশ্চিত করুন। - Multithreading Consideration: RequestScope সাধারণত থ্রেডে নিরাপদ, কিন্তু আপনি যদি সিঙ্ক্রোনাইজেশন বা থ্রেডের জন্য আলাদা ডিপেনডেন্সি চান, তবে থ্রেড-সেফ স্কোপ ব্যবহার করুন।
Guice-এ Request Scope একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা HTTP রিকোয়েস্টের জন্য আলাদা ডিপেনডেন্সি তৈরি করে। Guice Servlet Module এর মাধ্যমে Request Scope সহজেই কনফিগার করা যায়, যা সাধারণত ওয়েব অ্যাপ্লিকেশন এবং মাল্টিথ্রেডেড পরিবেশে ব্যবহৃত হয়। এটি ডিপেনডেন্সির লাইফসাইকেল এবং পারফরম্যান্সকে আরও কার্যকরীভাবে পরিচালনা করতে সাহায্য করে।
Request Scope হল Guice-এর একটি বিশেষ scope যা নিশ্চিত করে যে একটি নির্দিষ্ট ডিপেনডেন্সি শুধুমাত্র একটি HTTP রিকোয়েস্টের সময়কাল পর্যন্ত জীবিত থাকবে। এর মাধ্যমে, আপনি নিশ্চিত হতে পারেন যে একটি ডিপেনডেন্সি (যেমন, সার্ভিস বা অবজেক্ট) শুধুমাত্র একটি HTTP রিকোয়েস্টের জন্য তৈরি হবে এবং রিকোয়েস্ট শেষে এটি স্বয়ংক্রিয়ভাবে ধ্বংস (garbage collected) হয়ে যাবে।
Guice-এ RequestScope একটি গুরুত্বপূর্ণ life-cycle management কৌশল যেখানে আপনি প্রতিটি HTTP রিকোয়েস্টের জন্য নির্দিষ্ট অবজেক্ট বা ডিপেনডেন্সি আলাদা ভাবে ব্যবহার করতে পারেন।
Request Scope কীভাবে কাজ করে?
- Life-cycle: Request Scope ডিপেনডেন্সি শুধুমাত্র HTTP রিকোয়েস্টের জন্য তৈরি হয়। প্রতিটি নতুন HTTP রিকোয়েস্টের জন্য নতুন একটি অবজেক্ট তৈরি হয়, এবং রিকোয়েস্ট শেষে সেই অবজেক্ট ধ্বংস হয়ে যায়।
- Stateful Components: Request Scope সাধারণত ব্যবহার করা হয় এমন কম্পোনেন্টগুলির জন্য যেখানে অবজেক্টের অবস্থা (state) রিকোয়েস্ট-ভিত্তিক থাকে। উদাহরণস্বরূপ, সার্ভিস লেয়ার, ইউজার সেশন সম্পর্কিত ডেটা অথবা রিকোয়েস্টের জন্য নির্দিষ্ট কনফিগারেশন যেখানে আপনি এক রিকোয়েস্টের মধ্যে রক্ষণাবেক্ষণ করতে চান।
- Multiple Request Handling: যখন একাধিক HTTP রিকোয়েস্ট থাকে, তখন প্রতিটি রিকোয়েস্টের জন্য একটি নতুন ইনস্ট্যান্স তৈরি হবে। এতে রিকোয়েস্ট-ভিত্তিক ডেটার বিভাজন সহজ হয়।
Request Scope ব্যবহারের প্রয়োজনীয়তা
- Stateful Dependencies for Each Request:
- অনেক সময় এমন ডিপেনডেন্সির প্রয়োজন হয় যা রিকোয়েস্টের মধ্যে একাধিক মান বা অবস্থা ধারণ করতে পারে। যেমন, ইউজারের লগইন স্টেট, সেশন ডেটা, ট্রানজেকশন আইডি ইত্যাদি। Request Scope ব্যবহার করে আপনি এই ধরনের ডিপেনডেন্সি একটি HTTP রিকোয়েস্টের মধ্যে সীমাবদ্ধ রাখতে পারেন।
- Performance Optimization:
- Request Scope ব্যবহারের মাধ্যমে আপনি একাধিক রিকোয়েস্টের জন্য একাধিক অবজেক্ট তৈরি করতে না হয়ে, এক রিকোয়েস্টে শুধুমাত্র একটি ইনস্ট্যান্স তৈরি করবেন। এতে মেমরি ব্যবস্থাপনা আরও কার্যকর হতে পারে, এবং এটি অ্যাপ্লিকেশনের কর্মক্ষমতা বাড়াতে সাহায্য করতে পারে।
- Separation of Concerns:
RequestScopeব্যবহারের মাধ্যমে আপনি কোডের মধ্যে সঠিকভাবে অবস্থা এবং কার্যকারিতা আলাদা করতে পারেন। এটি মূলত Separation of Concerns ধারণা বজায় রাখতে সাহায্য করে, যেখানে রিকোয়েস্ট-ভিত্তিক স্টেট কোডের অন্যান্য অংশ থেকে আলাদা রাখা হয়।
- Thread Safety:
- Guice-এর Request Scope এর ডিপেনডেন্সিগুলি থ্রেড-সেফ থাকে, কারণ প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা অবজেক্ট তৈরি হয়, এবং একাধিক থ্রেড একই অবজেক্ট শেয়ার করেনা।
- Simplifying Complex Dependencies:
- কিছু অ্যাপ্লিকেশন যেমন ট্রানজেকশন পরিচালনা বা সেশন ম্যানেজমেন্ট, যেখানে একই রিকোয়েস্টে একাধিক সার্ভিসের মধ্যে ডেটা শেয়ার করা দরকার, সেখানে Request Scope সহায়ক হতে পারে। এতে আপনাকে একই ইনস্ট্যান্স বারবার তৈরি করতে হবে না।
Guice-এ Request Scope কিভাবে ব্যবহার করবেন
Guice-এ RequestScope ব্যবহার করতে, আপনাকে RequestScope যোগ করতে হবে এবং @RequestScoped অ্যানোটেশন ব্যবহার করতে হবে। Guice সাধারণত একটি Servlet-based কনটেক্সটে কাজ করার সময় RequestScope ব্যবহার করা হয়, যেহেতু এটি HTTP রিকোয়েস্টের সাথে সম্পর্কিত।
Step 1: Guice Module তৈরি করা
Guice Module-এর মধ্যে, আপনি @RequestScoped অ্যানোটেশন ব্যবহার করে একটি ক্লাসকে RequestScope-এ বাইন্ড করতে পারেন।
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.servlet.RequestScoped;
public class AppModule extends AbstractModule {
@Override
protected void configure() {
// Service ক্লাসকে RequestScope-এ বাইন্ড করা
bind(Service.class).in(RequestScoped.class);
}
}
Step 2: Service Interface এবং Implementation তৈরি করা
public interface Service {
void performTask();
}
@RequestScoped
public class ServiceImpl implements Service {
@Override
public void performTask() {
System.out.println("Service task performed!");
}
}
Step 3: Injector তৈরি এবং Request Scope ব্যবহার করা
Guice Injector তৈরি করুন এবং আপনি যেখানে চাইবেন সেখানে RequestScoped ডিপেনডেন্সি ইনজেক্ট করুন।
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.ServletModule;
public class MainApp {
public static void main(String[] args) {
// Guice Injector তৈরি করা
Injector injector = Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
// মডিউল কনফিগারেশন
}
}, new AppModule());
// Service এর RequestScoped ইনস্ট্যান্স রেজোলভ করা
Service service = injector.getInstance(Service.class);
service.performTask();
}
}
এখানে, যখন HTTP রিকোয়েস্ট আসে, ServiceImpl এর একটি নতুন ইনস্ট্যান্স তৈরি হবে এবং সেটা রিকোয়েস্ট শেষে ধ্বংস হয়ে যাবে।
Request Scope এর সুবিধা
- User Session Management:
- সেশনের ডেটা বা ইউজারের অবস্থা (যেমন লগইন স্টেট) একাধিক রিকোয়েস্টে ব্যবহার করা যায়। এক রিকোয়েস্টের মধ্যে নতুন ইউজার ডেটা ইনজেক্ট হবে এবং পরবর্তী রিকোয়েস্টে নতুন ইনস্ট্যান্স তৈরি হবে।
- Transaction Management:
- ট্রানজেকশন আইডি বা ডেটাবেস কানেকশনকে শুধুমাত্র একটি HTTP রিকোয়েস্টের মধ্যে সীমাবদ্ধ করা যায়, যা বিভিন্ন ধরণের রিকোয়েস্টের মধ্যে একে অপরকে প্রভাবিত না হতে দেয়।
- Simplifying Complex Systems:
- কিছু অ্যাপ্লিকেশনে যেখানে ইউজারের সেশন, লগিং, অথবা প্রক্রিয়াগত ডেটা একাধিক সার্ভিসের মধ্যে শেয়ার করতে হয়, সেখানে
RequestScopeডিপেনডেন্সির সঠিক ব্যবস্থাপনা সহজতর করে।
- কিছু অ্যাপ্লিকেশনে যেখানে ইউজারের সেশন, লগিং, অথবা প্রক্রিয়াগত ডেটা একাধিক সার্ভিসের মধ্যে শেয়ার করতে হয়, সেখানে
- RequestScope Guice এর একটি গুরুত্বপূর্ণ scope, যা HTTP রিকোয়েস্টের জন্য ডিপেনডেন্সি লাইফসাইকেল পরিচালনা করতে সাহায্য করে।
- এটি stateful ডিপেনডেন্সি যেমন সেশন ম্যানেজমেন্ট, ট্রানজেকশন আইডি, বা ইউজারের লগইন স্টেটের জন্য প্রয়োজনীয়।
- Performance optimization, Separation of Concerns, এবং Thread Safety নিশ্চিত করতে RequestScope অত্যন্ত কার্যকরী।
Guice-এ Request Scope ব্যবস্থাপনা করার মাধ্যমে, আপনি নিশ্চিত করতে পারেন যে একটি নির্দিষ্ট HTTP রিকোয়েস্টে কেবল একটি ইনস্ট্যান্স তৈরি হবে, যা রিকোয়েস্টের জীবনকাল জুড়ে থাকবে। Guice-এ Request Scope ব্যবস্থাপনা সাধারণত Servlets বা JAX-RS (RESTful Web Services) এর মাধ্যমে করা হয়, যেখানে প্রতি HTTP রিকোয়েস্টের জন্য একটি পৃথক ইনস্ট্যান্স তৈরি করা হয়।
Guice-এ Request Scope ব্যবস্থাপনা করার জন্য আপনাকে @RequestScope অ্যানোটেশন ব্যবহার করতে হবে অথবা Guice এর Scope API ব্যবহার করতে হবে। এটি সাধারণত ওয়েব অ্যাপ্লিকেশন, যেখানে HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্সের প্রয়োজন, সেখানে ব্যবহৃত হয়।
Guice Request Scope ব্যবস্থাপনা
1. Guice Request Scope কনফিগারেশন
Guice-এ Request Scope ব্যবস্থাপনা করতে, আপনাকে Guice Injector-এ @RequestScope অ্যানোটেশন ব্যবহার করতে হবে। সাধারণত, Guice এই স্কোপটি Servlet এর সাথে একত্রে ব্যবহৃত হয়।
Step 1: Guice এর জন্য RequestScope তৈরি করা
Guice-এ @RequestScope একটি কাস্টম স্কোপ তৈরি করতে সাহায্য করে। এটি নিশ্চিত করে যে একটি HTTP রিকোয়েস্টের মধ্যে একটি ক্লাসের কেবল একটি ইনস্ট্যান্স থাকবে।
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.servlet.ServletModule;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MyService.class).in(RequestScoped.class); // RequestScope ইনজেকশন
}
}
এখানে, RequestScoped.class ব্যবহার করে আমরা MyService ক্লাসকে Request Scope-এ বাইন্ড করেছি। এর মানে হল যে এক HTTP রিকোয়েস্টের মধ্যে MyService-এর একটি ইনস্ট্যান্স থাকবে এবং সেটি নতুন রিকোয়েস্টে পুনরায় তৈরি হবে না।
Step 2: @RequestScope অ্যানোটেশন ব্যবহার করা
Guice 4.0 এর পর, আপনি @RequestScoped অ্যানোটেশন ব্যবহার করে কোন ক্লাসকে Request Scope এ নির্দেশ করতে পারেন।
import com.google.inject.ScopeAnnotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ScopeAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestScoped {
}
এখন, আপনি RequestScoped অ্যানোটেশনটি কোনো ক্লাসে ব্যবহার করতে পারবেন যাতে এটি একটি নির্দিষ্ট HTTP রিকোয়েস্টের জন্য ইনস্ট্যান্স তৈরি হয়।
Step 3: MyService ক্লাস তৈরি করা
@RequestScoped
public class MyService {
public void performAction() {
System.out.println("Request Scoped Service executed!");
}
}
এখানে, MyService ক্লাসটি RequestScoped অ্যানোটেশন দ্বারা মার্ক করা হয়েছে, যার মানে এক HTTP রিকোয়েস্টের মধ্যে এর একটাই ইনস্ট্যান্স থাকবে।
Step 4: Guice-এ Request Scope ব্যবহার
এখন, Guice.createInjector() ব্যবহার করে Guice Injector তৈরি করুন এবং MyService-এর ইনস্ট্যান্সটি HTTP রিকোয়েস্টের জন্য ইনজেক্ট করুন।
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.servlet.ServletModule;
public class MainApp {
private final MyService myService;
@Inject
public MainApp(MyService myService) {
this.myService = myService;
}
public void execute() {
myService.performAction();
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new ServletModule(), new MyModule());
// Here, we simulate a request-scoped service invocation
MainApp app = injector.getInstance(MainApp.class);
app.execute();
}
}
এখানে, MainApp ক্লাসে MyService ইনজেক্ট করা হচ্ছে। Guice.createInjector() এর মাধ্যমে Guice Injector তৈরি হচ্ছে এবং Guice নিশ্চিত করছে যে MyService এর একটিমাত্র ইনস্ট্যান্স HTTP রিকোয়েস্টের জন্য থাকবে।
2. Guice Servlet Integration
Guice-এর Servlet Module ব্যবহার করে, আপনি HTTP রিকোয়েস্টের জন্য Request Scope কনফিগার করতে পারেন।
Step 1: Guice Servlet Module অন্তর্ভুক্ত করা
Guice Servlet Module Guice-কে HTTP রিকোয়েস্ট সাইকেল বুঝতে সাহায্য করে এবং এতে @RequestScoped ইনস্ট্যান্স তৈরি হয়।
import com.google.inject.servlet.ServletModule;
public class WebModule extends ServletModule {
@Override
protected void configureServlets() {
bind(MyService.class).in(RequestScoped.class); // RequestScope in Servlet
}
}
এখানে, ServletModule ব্যবহার করে আমরা Guice Servlet কনফিগারেশন তৈরি করছি, যেখানে MyService কে Request Scope-এ বাইন্ড করা হয়েছে।
Step 2: Guice Filter ব্যবহার করে Request Scope
Guice-এ RequestScope ব্যবস্থাপনা করতে, Guice ফিল্টার ব্যবহার করতে হয়, যা HTTP রিকোয়েস্টের সময় স্কোপ সৃষ্টি করে।
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceFilter;
public class MyGuiceFilter extends GuiceFilter {
private final Injector injector;
public MyGuiceFilter(Injector injector) {
this.injector = injector;
}
@Override
protected Injector getInjector() {
return injector;
}
}
এখানে, GuiceFilter ব্যবহার করে Guice নিশ্চিত করে যে রিকোয়েস্টের জন্য সঠিক স্কোপ পরিচালিত হচ্ছে।
3. Request Scope ব্যবহার করার উপকারিতা
- Request-ভিত্তিক ইনস্ট্যান্স: যেকোনো HTTP রিকোয়েস্টের জন্য নির্দিষ্ট ইনস্ট্যান্স তৈরি হওয়া, যা পুনঃব্যবহারযোগ্য কিন্তু এক রিকোয়েস্টের মধ্যে নতুন ইনস্ট্যান্স তৈরি হয়।
- Web Applications: Web অ্যাপ্লিকেশনগুলোতে Request Scope সাধারণত ব্যবহার হয় যাতে প্রতিটি HTTP রিকোয়েস্টের জন্য পৃথক অবজেক্ট থাকে।
- Stateful Services: কিছু সার্ভিসে যেখানে স্টেটful ডেটা রাখা প্রয়োজন, Request Scope তার জন্য আদর্শ। এতে, রিকোয়েস্টের মধ্যে স্টেট রাখা হয় এবং অন্য রিকোয়েস্টে তার কোন প্রভাব পড়ে না।
Guice-এ Request Scope ব্যবস্থাপনা HTTP রিকোয়েস্ট সাইকেল ভিত্তিক স্কোপ নিশ্চিত করে এবং নিশ্চিত করে যে আপনার প্রয়োজনীয় ক্লাসের ইনস্ট্যান্স এক HTTP রিকোয়েস্টের মধ্যে একটাই থাকবে। এটি সাধারণত Servlets বা Web Applications-এ ব্যবহৃত হয়, যেখানে HTTP রিকোয়েস্টের জন্য বিশেষ ইনস্ট্যান্স প্রয়োজন হয়। Guice দিয়ে এটি করতে @RequestScope অ্যানোটেশন এবং Guice Servlet Module ব্যবহার করা হয়, যা সহজে স্কেলেবল এবং কার্যকরী ডিজাইন প্রদান করে।
Guice-এ Request Scope এমন একটি scope যা HTTP রিকোয়েস্টের লাইফসাইকেল ধরে থাকে। অর্থাৎ, যখন একটি HTTP রিকোয়েস্ট আসে, তখন একটি নির্দিষ্ট ডিপেনডেন্সি একটি নতুন ইনস্ট্যান্স হিসেবে তৈরি হবে এবং সেই রিকোয়েস্টের শেষ পর্যন্ত সেই ইনস্ট্যান্স থাকবে। এই ধরনের স্কোপ সাধারণত web applications-এ ব্যবহৃত হয় যেখানে আপনাকে রিকোয়েস্ট স্পেসিফিক ডেটা বা অবজেক্টগুলো ম্যানেজ করতে হয়।
Guice নেটিভলি Request Scope সাপোর্ট করে না, তবে Guice এর Servlet Integration ব্যবহার করে আপনি সহজেই রিকোয়েস্ট স্কোপ সেট আপ করতে পারেন। এটি Servlet Filter বা Guice এর RequestScope ক্লাসের মাধ্যমে করা যায়।
এখানে Web Applications-এ Request Scope ব্যবহার করার জন্য একটি উদাহরণ দেওয়া হলো।
Request Scope ব্যবহারের ধাপসমূহ
- Guice Servlet Module যোগ করা
- Request Scope ক্লাস তৈরি করা
- Guice-এ Request Scope কনফিগার করা
- Request Scope ডিপেনডেন্সি ব্যবহার করা
1. Guice Servlet Module যোগ করা
প্রথমে, আপনাকে Guice Servlet Module ইন্টিগ্রেট করতে হবে। এর মাধ্যমে Guice-এর Request Scope কার্যকরী হবে।
Maven Dependency:
Guice Servlet Integration এর জন্য, Maven পম ফাইলে নিচের ডিপেনডেন্সি যোগ করুন:
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice-servlet</artifactId>
<version>5.1.0</version>
</dependency>
Web.xml কনফিগারেশন:
এছাড়াও, web.xml ফাইলে Guice Servlet এর জন্য কনফিগারেশন করতে হবে।
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<servlet>
<servlet-name>guiceServlet</servlet-name>
<servlet-class>com.google.inject.servlet.GuiceServletContextListener</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>guiceServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2. Request Scope ক্লাস তৈরি করা
Guice-এ Request Scope সেটআপ করতে, প্রথমে একটি ক্লাস তৈরি করতে হবে যা রিকোয়েস্ট স্পেসিফিক ডেটা ধারন করবে।
RequestScopedService.java:
import com.google.inject.Inject;
import com.google.inject.Provider;
public class RequestScopedService {
private final String requestId;
@Inject
public RequestScopedService() {
// Set some unique identifier for the request
this.requestId = "Request ID: " + System.nanoTime();
}
public String getRequestId() {
return requestId;
}
}
এখানে RequestScopedService ক্লাসটি রিকোয়েস্টের সময় একটি ইউনিক আইডেন্টিফায়ার তৈরি করবে।
3. Guice-এ Request Scope কনফিগার করা
এখন, RequestScope কনফিগার করতে হবে Guice মডিউলে। আমরা Guice Servlet API-র মাধ্যমে RequestScope অ্যাকটিভেট করব।
AppModule.java:
import com.google.inject.AbstractModule;
import com.google.inject.servlet.RequestScoped;
public class AppModule extends AbstractModule {
@Override
protected void configure() {
// Request Scoped Service bind
bind(RequestScopedService.class).in(RequestScoped.class);
}
}
এখানে RequestScopedService-কে RequestScoped হিসেবে ব্যন্ড করা হয়েছে।
4. Request Scope ডিপেনডেন্সি ব্যবহার করা
এখন, আপনি Guice Servlet ব্যবহার করে একটি HTTP রিকোয়েস্টে RequestScopedService ইনজেক্ট করতে পারেন।
Example Servlet:
import com.google.inject.Inject;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
private final RequestScopedService requestScopedService;
@Inject
public MyServlet(RequestScopedService requestScopedService) {
this.requestScopedService = requestScopedService;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Retrieve and display the request scoped service data
resp.getWriter().write("Request Scoped ID: " + requestScopedService.getRequestId());
}
}
web.xml (Servlet Mapping):
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/requestScopeExample</url-pattern>
</servlet-mapping>
এখন আপনি /requestScopeExample URL এ HTTP GET রিকোয়েস্ট করলে, রিকোয়েস্ট স্কোপের মধ্যে RequestScopedService ইনস্ট্যান্স তৈরি হবে এবং এর requestId রিটার্ন হবে।
5. Request Scope এর কাজের দৃষ্টান্ত
যখন আপনি বিভিন্ন রিকোয়েস্টে /requestScopeExample URL এ রিকোয়েস্ট পাঠাবেন, প্রতিটি রিকোয়েস্টের জন্য একটি আলাদা requestId তৈরি হবে। প্রতিটি রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি হওয়ায়, রিকোয়েস্টের মধ্যে ডেটা সংরক্ষিত থাকে এবং অন্যান্য রিকোয়েস্টের সাথে মিলিত হয় না।
Output:
Request Scoped ID: Request ID: 1234567890123
এটি নিশ্চিত করে যে, প্রতিটি রিকোয়েস্টে RequestScopedService এর একটি নতুন ইনস্ট্যান্স তৈরি হবে এবং তার নিজস্ব requestId থাকবে।
Guice-এ Request Scope ব্যবহারের মাধ্যমে আপনি সহজেই HTTP রিকোয়েস্টের লাইফসাইকেল নির্ধারণ করে রিকোয়েস্ট স্পেসিফিক ডিপেনডেন্সি ম্যানেজ করতে পারেন। Guice Servlet Integration-এর মাধ্যমে আপনি RequestScoped অ্যানোটেশন ব্যবহার করে HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি করতে পারেন, যা আপনার ওয়েব অ্যাপ্লিকেশনের ডেটা এবং অবজেক্ট ম্যানেজমেন্টে অনেক সাহায্য করে।
Guice Dependency Injection Framework এ Request Scope এবং Singleton Scope দুটি ভিন্ন ধরনের সিঙ্গলটন স্কোপ রয়েছে। এই স্কোপ দুটি ডিপেন্ডেন্সির জীবনকাল (lifetime) এবং ইনস্ট্যান্স তৈরির কৌশলে পার্থক্য রাখে।
1. Singleton Scope
Singleton Scope এমন একটি স্কোপ যেখানে অবজেক্টটি পুরো অ্যাপ্লিকেশন চলাকালীন একবার তৈরি হয় এবং সমস্ত রিকোয়েস্টের জন্য একই ইনস্ট্যান্স ব্যবহার করা হয়। এর মানে হল যে, একবার একটি অবজেক্ট তৈরি হলে সেটি পুনরায় ব্যবহার করা হবে যতবারই প্রয়োজন হোক না কেন।
Key Features of Singleton Scope:
- একটি ইনস্ট্যান্স: অ্যাপ্লিকেশন চলাকালীন শুধুমাত্র একবার ইনস্ট্যান্স তৈরি হয়।
- Global Instance: সমস্ত ক্লাস বা রিকোয়েস্ট একই ইনস্ট্যান্স ব্যবহার করে।
- Performance: দ্রুত, কারণ একবার ইনস্ট্যান্স তৈরি হলে পুনরায় সেটি তৈরি করতে হয় না।
- Memory Usage: একটি ইনস্ট্যান্সের জন্য সবসময় মেমরি থাকে, যা কখনও কখনও অপ্রয়োজনীয় রিসোর্স খরচ হতে পারে।
Usage Example:
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class).in(Singleton.class); // Singleton Scope
}
}
public class Service {
public Service() {
System.out.println("Service Created");
}
public void execute() {
System.out.println("Executing service");
}
}
এখানে, Service ক্লাসে Singleton Scope ব্যবহার করা হয়েছে, যার মানে এটি শুধুমাত্র একবার তৈরি হবে এবং সব জায়গায় একই ইনস্ট্যান্স ব্যবহার হবে।
2. Request Scope
Request Scope হল এমন একটি স্কোপ যেখানে অবজেক্টটি একটি নির্দিষ্ট HTTP রিকোয়েস্টের জন্য তৈরি হয় এবং রিকোয়েস্টের শেষে সেটি ধ্বংস হয়ে যায়। এটি সাধারণত ওয়েব অ্যাপ্লিকেশনে ব্যবহৃত হয় যেখানে একটি রিকোয়েস্টের জন্য আলাদা অবজেক্ট তৈরি করতে হয়, এবং সেই অবজেক্টটি পরবর্তী রিকোয়েস্টে পুনরায় ব্যবহৃত হয় না।
Key Features of Request Scope:
- One Instance Per Request: প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি হয়।
- Scope Bound to Request Lifetime: অবজেক্টটি শুধুমাত্র একটি রিকোয়েস্টের জন্য জীবিত থাকে এবং রিকোয়েস্ট শেষ হলে ধ্বংস হয়ে যায়।
- Memory Efficiency: প্রতিটি রিকোয়েস্টের জন্য একটি নতুন ইনস্ট্যান্স তৈরি হয়, যা যেকোনো কনটেক্সটে প্রয়োজনীয় ডেটা রাখতে সহায়ক হতে পারে।
- Usage: ওয়েব অ্যাপ্লিকেশন বা REST API ইত্যাদিতে সাধারণত ব্যবহৃত হয়।
Usage Example (Request Scope):
import com.google.inject.AbstractModule;
import com.google.inject.Scope;
import com.google.inject.servlet.RequestScoped;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class).in(RequestScoped.class); // Request Scope
}
}
@RequestScoped
public class Service {
public Service() {
System.out.println("Service Created for Request");
}
public void execute() {
System.out.println("Executing service");
}
}
এখানে, Service ক্লাসের জন্য Request Scope ব্যবহার করা হয়েছে। এর মানে হল যে, প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি হবে এবং সেই রিকোয়েস্ট শেষ হলে তা ধ্বংস হয়ে যাবে।
পার্থক্য: Singleton Scope vs Request Scope
| বৈশিষ্ট্য | Singleton Scope | Request Scope |
|---|---|---|
| ইনস্ট্যান্স তৈরি | একবার তৈরি হয় এবং অ্যাপ্লিকেশন চলাকালীন পুনরায় ব্যবহার করা হয়। | প্রতি HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি হয়। |
| লাইফটাইম | অ্যাপ্লিকেশন লাইফটাইম পর্যন্ত। | শুধুমাত্র একটি HTTP রিকোয়েস্টের জন্য। |
| রিসোর্স ব্যবস্থাপনা | সব রিকোয়েস্ট একই ইনস্ট্যান্স ব্যবহার করে, কম রিসোর্স ব্যবহার হয়। | নতুন ইনস্ট্যান্স তৈরি হয়, রিসোর্স কিছুটা বেশি হতে পারে। |
| ব্যবহার | যেসব ডেটা অ্যাপ্লিকেশন জুড়ে শেয়ার করা হয় (যেমন ক্যাশিং)। | যেসব ডেটা একটি নির্দিষ্ট রিকোয়েস্টের মধ্যে ব্যবহৃত হয়। |
| উদাহরণ | একক সার্ভিস ক্লাস বা ডেটাবেস কানেকশন। | HTTP রিকোয়েস্ট বা ওয়েব সার্ভিসের জন্য ডিপেন্ডেন্সি। |
- Singleton Scope ব্যবহৃত হয় এমন অবজেক্টের জন্য যেগুলি অ্যাপ্লিকেশন জীবনের মধ্যে একাধিকবার ব্যবহার করা হয়, এবং একবার তৈরি হলে সেগুলি পুনরায় তৈরি করার প্রয়োজন পড়ে না।
- Request Scope সাধারণত HTTP রিকোয়েস্ট-ভিত্তিক অবজেক্ট তৈরি করার জন্য ব্যবহৃত হয়, যেখানে প্রতি রিকোয়েস্টের জন্য নতুন ইনস্ট্যান্স তৈরি হয় এবং রিকোয়েস্টের শেষে এটি ধ্বংস হয়ে যায়।
আপনি যে ধরনের স্কোপ ব্যবহার করবেন তা নির্ভর করে আপনার অ্যাপ্লিকেশনের প্রয়োজনীয়তার উপর। যদি একটি সার্ভিস বা ডেটাবেস কানেকশন অ্যাপ্লিকেশনজুড়ে শেয়ার করতে চান তবে Singleton Scope হবে সঠিক পছন্দ। তবে যদি আপনার অবজেক্টটি শুধুমাত্র একটি নির্দিষ্ট HTTP রিকোয়েস্টের জন্য প্রয়োজন হয়, তবে Request Scope ব্যবহার করা উচিত।
Read more