Guice একটি শক্তিশালী Dependency Injection (DI) ফ্রেমওয়ার্ক যা ডিপেনডেন্সি ইনজেকশনের জন্য automatic lifecycle management প্রদান করে। তবে, কখনও কখনও আপনাকে কাস্টম লাইফসাইকেল ম্যানেজমেন্টের প্রয়োজন হতে পারে, যেমন একটি নির্দিষ্ট অবজেক্টের তৈরি হওয়া এবং ধ্বংস হওয়ার জন্য কাস্টম নিয়ম তৈরি করা। Guice আপনাকে এটি করার জন্য বিভিন্ন পদ্ধতি প্রদান করে।
এখানে, আমরা দেখব কিভাবে Guice-এ Custom Lifecycle Management তৈরি করা যায়, যাতে আপনি ডিপেনডেন্সিগুলির lifecycle (অবজেক্টের সৃষ্টি এবং ধ্বংস) কাস্টমাইজ করতে পারেন।
1. Guice-এ Lifecycle Management
Guice নিজেই singleton, scoped, এবং transient লাইফসাইকেলগুলো পরিচালনা করে, তবে কখনও কখনও আপনাকে custom lifecycle তৈরি করতে হতে পারে, যেখানে অবজেক্টের নির্মাণ এবং ধ্বংস আরও কাস্টমাইজড হবে।
এখানে কিছু custom lifecycle management কৌশল দেখানো হলো:
2. Guice-এ Custom Scope তৈরি করা
Guice-এ আপনি Custom Scopes তৈরি করতে পারেন, যা নির্দিষ্ট একটি অবজেক্টের লাইফসাইকেল নিয়ন্ত্রণ করবে। উদাহরণস্বরূপ, আপনি একটি request-scoped বা session-scoped অবজেক্ট তৈরি করতে পারেন।
ধাপ 1: Custom Scope তৈরি করা
এখানে একটি উদাহরণ দেখানো হলো যেখানে আমরা একটি CustomScope তৈরি করব।
import com.google.inject.Scope;
import com.google.inject.spi.ScopeAnnotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// Custom annotation for our scope
@Retention(RetentionPolicy.RUNTIME)
@ScopeAnnotation
public @interface CustomScope {}
// Custom scope implementation
public class CustomScopeImpl implements Scope {
private static final ThreadLocal<Object> threadLocal = new ThreadLocal<>();
@Override
public <T> com.google.inject.Provider<T> scope(Key<T> key, com.google.inject.Provider<T> unscoped) {
return new com.google.inject.Provider<T>() {
@Override
public T get() {
T instance = (T) threadLocal.get();
if (instance == null) {
instance = unscoped.get();
threadLocal.set(instance);
}
return instance;
}
};
}
public static void clear() {
threadLocal.remove();
}
}
ধাপ 2: Custom Scope ব্যবহার করা
এখন আমরা CustomScope ব্যবহার করে একটি নির্দিষ্ট ইনস্ট্যান্স তৈরি এবং ব্যবহারের জন্য @CustomScope অ্যানোটেশন ব্যবহার করব।
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;
// Simple class for demonstration
public class MyService {
private final String name;
@Inject
public MyService() {
this.name = "Custom Scoped Service";
}
public String getName() {
return name;
}
}
// Guice Module
public class MyModule extends AbstractModule {
@Override
protected void configure() {
// Install the custom scope
bindScope(CustomScope.class, new CustomScopeImpl());
bind(MyService.class).in(CustomScope.class);
}
}
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
// Create multiple instances of MyService
MyService service1 = injector.getInstance(MyService.class);
MyService service2 = injector.getInstance(MyService.class);
// Both instances are the same because they are in the CustomScope
System.out.println(service1.getName());
System.out.println(service2.getName());
System.out.println(service1 == service2); // Output: true (singleton within CustomScope)
}
}
Explanation:
- এখানে
CustomScopeতৈরি করা হয়েছে এবং এটি thread-local storage ব্যবহার করছে। এর মানে হল যে একে একে থ্রেডের মধ্যে একই অবজেক্ট ইনজেক্ট হবে। @CustomScopeঅ্যানোটেশন ব্যবহার করেMyServiceক্লাসের ইনস্ট্যান্সটি CustomScope-এর মধ্যে থাকবে।
3. Guice Lifecycle Hooks
Guice আপনাকে custom lifecycle management করতে Lifecycle Hooks প্রদান করে, যেমন @PostConstruct এবং @PreDestroy অ্যানোটেশন ব্যবহার করে ডিপেনডেন্সির লাইফসাইকেল পরিচালনা করা।
ধাপ 1: @PostConstruct এবং @PreDestroy ব্যবহার
Guice-এর মাধ্যমে @PostConstruct এবং @PreDestroy লাইফসাইকেল হুকগুলো ব্যবহার করা যায়, যা অবজেক্টের তৈরি হওয়ার পরে এবং ধ্বংস হওয়ার আগে কিছু কাজ করতে সাহায্য করে।
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class LifecycleService {
@PostConstruct
public void init() {
System.out.println("LifecycleService initialized");
}
@PreDestroy
public void cleanup() {
System.out.println("LifecycleService cleaned up");
}
public void serve() {
System.out.println("Service is being served...");
}
}
ধাপ 2: Guice Module-এ Lifecycle Hooks ব্যবহার
এখন, আমাদের Guice Module তৈরি করতে হবে এবং LifecycleService এর জন্য লাইফসাইকেল হুক ব্যবহার করতে হবে।
import com.google.inject.AbstractModule;
public class LifecycleModule extends AbstractModule {
@Override
protected void configure() {
bind(LifecycleService.class).asEagerSingleton(); // Create eagerly initialized singleton
}
}
ধাপ 3: Injector-এ Lifecycle Management ব্যবহার
import com.google.inject.Guice;
import com.google.inject.Injector;
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new LifecycleModule());
// Get instance of LifecycleService
LifecycleService lifecycleService = injector.getInstance(LifecycleService.class);
lifecycleService.serve();
// Cleanup occurs when the application is shut down
injector.getInstance(LifecycleService.class); // Here cleanup would happen (on application exit)
}
}
Explanation:
@PostConstructএবং@PreDestroyহুক ব্যবহার করে আমরা অবজেক্ট তৈরি হওয়ার পরে কিছু কাজ করতে এবং অবজেক্ট ধ্বংসের আগে কিছু কাজ করতে পারি।asEagerSingleton()ব্যবহার করলে Guice অবজেক্টটি তৈরি করার সময়@PostConstructহুক কল করবে এবং অবজেক্ট ধ্বংস হওয়ার সময়@PreDestroyকল হবে।
4. Guice Lifecycle Management এর সুবিধা
- Custom Scopes:
- আপনি কাস্টম স্কোপ তৈরি করতে পারেন যেমন session-scoped, request-scoped, বা আরও কাস্টম স্কোপের জন্য ডিপেনডেন্সি ম্যানেজমেন্ট করতে পারেন।
- এটি Guice-এ বিভিন্ন অবজেক্টের জন্য কাস্টম লাইফসাইকেল প্রয়োগ করার সুযোগ দেয়।
- Explicit Initialization & Cleanup:
- Lifecycle Hooks (
@PostConstruct,@PreDestroy) ব্যবহার করার মাধ্যমে আপনি অবজেক্টের ইন্টিগ্রেশন আরও পরিষ্কারভাবে এবং নিয়ন্ত্রিতভাবে করতে পারেন। - কাস্টম ডেস্ট্রাকশন লজিক বা ইনিশিয়ালাইজেশন লজিক প্রয়োগ করা সহজ হয়।
- Lifecycle Hooks (
- Thread-Safe Lifecycle:
- Thread-local scoping ব্যবহার করে, আপনি থ্রেডে বিশেষ লাইফসাইকেল ম্যানেজমেন্ট করতে পারেন, যা মাল্টিথ্রেডেড পরিবেশে গুরুত্বপূর্ণ।
- Custom Lifecycle Management Guice-এ অত্যন্ত নমনীয় এবং শক্তিশালী একটি ফিচার। আপনি custom scopes, lifecycle hooks, এবং thread-local storage ব্যবহার করে Guice-এর ডিপেনডেন্সি ইনজেকশন প্রক্রিয়াকে কাস্টমাইজ করতে পারেন।
- Guice আপনাকে dependency lifecycle আরও নিয়ন্ত্রিত এবং উপযুক্তভাবে পরিচালনা করার সুযোগ দেয়, বিশেষত যখন আপনি বিভিন্ন কাস্টম স্কোপ এবং ক্লিনআপ লজিক ব্যবহার করতে চান।
Read more