Skill

Guice এর মাধ্যমে Scope ব্যবস্থাপনা

গুইস (Guice) - Java Technologies

330

Guice একটি শক্তিশালী ডিপেনডেন্সি ইনজেকশন (DI) ফ্রেমওয়ার্ক যা ডিপেনডেন্সি ম্যানেজমেন্টকে সহজ করে তোলে এবং আপনাকে বিভিন্ন Scope ব্যবস্থাপনা করতে সাহায্য করে। Scope ব্যবস্থাপনার মাধ্যমে আপনি কোনো নির্দিষ্ট ডিপেনডেন্সির লাইফটাইম বা জীবনচক্র কাস্টমাইজ করতে পারেন। Guice-এ প্রধানত তিনটি প্রাথমিক Scope ব্যবহৃত হয়: Singleton, Scoped, এবং No Scope (Default Scope)


Guice এর মাধ্যমে Scope ব্যবস্থাপনা

১. Singleton Scope

Guice-এ Singleton Scope ব্যবহৃত হয় যখন আপনি চান যে একটি ক্লাসের একটিমাত্র ইনস্ট্যান্স ব্যবহার হোক অ্যাপ্লিকেশনের মধ্যে। Guice স্বয়ংক্রিয়ভাবে একমাত্র ইনস্ট্যান্স তৈরি করে এবং সেটি পুনঃব্যবহার করে।

Singleton Scope ব্যবহারের উদাহরণ

import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(GreetingService.class).to(GreetingServiceImpl.class).in(Singleton.class);
    }
}

এখানে, GreetingServiceImpl ক্লাসটি Singleton হিসেবে বাউন্ড হয়েছে, অর্থাৎ এটি একবারই তৈরি হবে এবং অ্যাপ্লিকেশনের মধ্যে একাধিক বার ব্যবহার করা হবে।

MainApp Example (Singleton Scope)

import com.google.inject.Guice;
import com.google.inject.Injector;

public class MainApp {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AppModule());

        GreetingService service1 = injector.getInstance(GreetingService.class);
        GreetingService service2 = injector.getInstance(GreetingService.class);

        // Check if both instances are the same
        System.out.println(service1 == service2);  // Output: true
    }
}

এখানে, service1 এবং service2 একই ইনস্ট্যান্স হবে কারণ Singleton Scope ব্যবহৃত হয়েছে।


২. Request Scope (Scoped)

Guice ডিফল্টভাবে No Scope দেয়, তবে আপনি যদি চান যে একটি ক্লাসের ইনস্ট্যান্স শুধুমাত্র একটি নির্দিষ্ট রিকোয়েস্ট বা প্রসেসে জীবিত থাকে, তাহলে @Scope ব্যবহার করতে হবে। Guice এ Request Scoped (যে ধরনের scope সাধারণত ওয়েব অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়) ব্যবস্থাপনার জন্য Guice অতিরিক্ত লাইব্রেরি যেমন Guice Servlet ব্যবহার করতে পারে।

Request Scope ব্যবহারের উদাহরণ

Guice সাধারণত Request Scope সরাসরি ম্যানেজ করতে পারে না, তবে একটি CustomScope তৈরি করা সম্ভব।

import com.google.inject.ScopeAnnotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@ScopeAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestScope {}

এটি কাস্টম স্কোপের জন্য একটি অ্যানোটেশন তৈরি করবে, তবে একে কার্যকরী করতে আপনাকে কাস্টম স্কোপ ম্যানেজার সেট আপ করতে হবে। তবে সাধারণ অ্যাপ্লিকেশনের জন্য, Guice এর Singleton এবং No Scope ব্যবস্থাপনা বেশি ব্যবহৃত হয়।


৩. No Scope (Default Scope)

Guice ডিফল্টভাবে No Scope ব্যবহৃত করে, যার মানে হল যে যখন একটি ডিপেনডেন্সি inject করা হয়, তখন সেটি প্রতি রিকোয়েস্টে একটি নতুন ইনস্ট্যান্স তৈরি হয়। অর্থাৎ, কোনো Singleton বা Scoped অ্যাট্রিবিউট ছাড়া ডিপেনডেন্সি ইনজেকশন করলে প্রতিবার নতুন ইনস্ট্যান্স তৈরি হবে।

No Scope ব্যবহারের উদাহরণ

import com.google.inject.AbstractModule;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(GreetingService.class).to(GreetingServiceImpl.class);
    }
}

এখানে, কোনো Scope নির্ধারণ করা হয়নি, তাই প্রতিবার GreetingService এর একটি নতুন ইনস্ট্যান্স তৈরি হবে।

MainApp Example (No Scope)

import com.google.inject.Guice;
import com.google.inject.Injector;

public class MainApp {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AppModule());

        GreetingService service1 = injector.getInstance(GreetingService.class);
        GreetingService service2 = injector.getInstance(GreetingService.class);

        // Check if both instances are different
        System.out.println(service1 == service2);  // Output: false
    }
}

এখানে, service1 এবং service2 আলাদা ইনস্ট্যান্স হবে কারণ No Scope ব্যবহৃত হয়েছে এবং প্রতিবার নতুন ইনস্ট্যান্স তৈরি হয়েছে।


Guice Scope এর উন্নত ব্যবহারের কৌশল

  1. Scope Customization: যদি আপনার বিশেষ কোনো স্কোপ প্রয়োজন হয়, তাহলে Guice আপনাকে Custom Scope তৈরি করার সুবিধা দেয়।
  2. Combination of Scopes: বিভিন্ন স্কোপের সমন্বয় ব্যবহারের মাধ্যমে জটিল ডিপেনডেন্সি ব্যবস্থাপনা করতে পারেন।
  3. Lazy Initialization: যখন কোনো ডিপেনডেন্সি Lazy Loaded হয়, তখন আপনি প্রয়োজন না হওয়া পর্যন্ত সেই ডিপেনডেন্সির ইনস্ট্যান্স তৈরি না করতে পারেন। Guice এ @Lazy অ্যানোটেশন ব্যবহার করে এই কাজটি করা যায়।

Best Practices for Scope Management in Guice

  1. Use Singleton for Shared Resources: যদি একটি ক্লাসের ইনস্ট্যান্স পুরো অ্যাপ্লিকেশনজুড়ে শেয়ার করতে চান, তবে Singleton ব্যবহার করুন।
  2. Avoid Memory Leaks in Request Scope: বিশেষভাবে ওয়েব অ্যাপ্লিকেশনগুলিতে, প্রতিটি HTTP রিকোয়েস্টের জন্য আলাদা ইনস্ট্যান্স তৈরি করলে অবাঞ্ছিত মেমরি লিক হতে পারে, তাই সঠিক স্কোপ নির্বাচন করুন।
  3. Scope Annotation Usage: Guice এ আপনার কাস্টম স্কোপ তৈরি করতে @ScopeAnnotation অ্যানোটেশন ব্যবহার করুন।
  4. Avoid Overuse of Scope: খুব বেশি স্কোপ ব্যবহারের ফলে কোডে জটিলতা আসতে পারে। যেখানে প্রয়োজন সেখানে স্কোপ ব্যবহার করুন।

Guice এর মাধ্যমে Scope ব্যবস্থাপনা একটি গুরুত্বপূর্ণ উপাদান যা ডিপেনডেন্সি ইনজেকশন প্রক্রিয়াকে আরও মডুলার এবং দক্ষ করে তোলে। Singleton, No Scope, এবং Scoped ব্যবস্থাপনা আপনাকে আপনার প্রয়োজন অনুযায়ী ডিপেনডেন্সির জীবনচক্র নিয়ন্ত্রণ করতে সহায়ক। সঠিকভাবে Scope ব্যবহারের মাধ্যমে আপনি অ্যাপ্লিকেশনের কর্মক্ষমতা ও রক্ষণাবেক্ষণযোগ্যতা বৃদ্ধি করতে পারবেন।

Content added By

Guice Scope হলো একটি কনসেপ্ট যা Guice Dependency Injection (DI) ফ্রেমওয়ার্কের মধ্যে ডিপেনডেন্সি ইনস্ট্যান্সের লাইফসাইকেল এবং সময় নির্ধারণ করে। একে scoped bindings বলা হয়, কারণ এটি নির্ধারণ করে যে একটি নির্দিষ্ট অবজেক্ট বা ডিপেনডেন্সি কখন তৈরি হবে এবং কত সময় পর্যন্ত তা জীবিত থাকবে।

Guice-এ scope ব্যবহার করে বিভিন্ন টাইপের ডিপেনডেন্সি সঞ্চালন করা হয়, যেমন singleton অবজেক্ট, বা request-ভিত্তিক অবজেক্ট। এটি ডিপেনডেন্সির ব্যবস্থাপনাকে আরও দক্ষ করে তোলে এবং আপনার অ্যাপ্লিকেশনকে আরো ভালভাবে স্কেলেবল এবং মেইনটেইনেবল করতে সাহায্য করে।


Guice Scope এর প্রকারভেদ

Guice বিভিন্ন ধরনের scopes প্রদান করে, যার মাধ্যমে আপনি কন্ট্রোল করতে পারেন একটি ইনস্ট্যান্স কিভাবে এবং কখন তৈরি হবে। সাধারণত, Guice তিনটি প্রধান scope সমর্থন করে:

1. Singleton Scope

  • Singleton Scope হল এমন একটি scope যেখানে একটি নির্দিষ্ট ক্লাসের শুধুমাত্র একটিই ইনস্ট্যান্স থাকবে। যখনই সেই ক্লাসের জন্য ডিপেনডেন্সি রেজোলভ করা হবে, এটি শুধুমাত্র প্রথম তৈরি হওয়া ইনস্ট্যান্স ফেরত দেবে।
  • গুরুত্ব: এটি আপনাকে সিস্টেমের মধ্যে একক অবজেক্ট শেয়ার করতে সাহায্য করে, যেমন ক্যাশ, লগার, বা ডাটাবেস সংযোগ।
উদাহরণ: Singleton Scope
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        // Service ইন্টারফেসের জন্য ServiceImpl ইমপ্লিমেন্টেশন নির্ধারণ, Singleton হিসেবে
        bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
    }
}

এখানে, ServiceImpl এর কেবল একটি ইনস্ট্যান্স হবে, যেটি পুরো অ্যাপ্লিকেশন জুড়ে শেয়ার হবে।

2. No Scope (Default)

  • যদি আপনি কোন scope নির্ধারণ না করেন, তবে Guice ডিফল্টভাবে No Scope ব্যবহার করে। অর্থাৎ, প্রতিবার Injector থেকে ডিপেনডেন্সি রেজোলভ করা হলে নতুন ইনস্ট্যান্স তৈরি হবে।
  • গুরুত্ব: এটা সাধারণত যেখানে নতুন নতুন অবজেক্ট প্রয়োজন হয়, যেমন ট্রানজেকশন বা সেশন-ভিত্তিক অবজেক্টে।
উদাহরণ: No Scope (Default)
import com.google.inject.AbstractModule;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        // Service ইন্টারফেসের জন্য ServiceImpl ইমপ্লিমেন্টেশন নির্ধারণ, No scope (Default)
        bind(Service.class).to(ServiceImpl.class);
    }
}

এখানে, ServiceImpl এর প্রতি ইনস্ট্যান্স কলের জন্য নতুন একটি ইনস্ট্যান্স তৈরি হবে।

3. Custom Scopes

  • Custom Scopes হল এমন scopes যা ব্যবহারকারীর চাহিদা অনুযায়ী তৈরি করা হয়। এগুলি সাধারণত নির্দিষ্ট সময়সীমা, সার্ভিস বা ট্রানজেকশনের ভিত্তিতে কাজ করে।
  • গুরুত্ব: এটি আপনাকে আরও বিশেষজ্ঞ বা কাস্টম লাইফসাইকেল ম্যানেজমেন্ট সরবরাহ করতে সাহায্য করে।
উদাহরণ: Custom Scope
import com.google.inject.*;
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@ScopeAnnotation
public @interface RequestScoped {}

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Service.class).to(ServiceImpl.class).in(RequestScoped.class);
    }
}

public class RequestScope implements Scope {
    @Override
    public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
        return () -> {
            // Custom request-scope logic
            return unscoped.get();
        };
    }
}

এখানে, RequestScoped একটি কাস্টম স্কোপ, যা ডিপেনডেন্সি তৈরি করার সময় নির্দিষ্ট জীবনচক্র বা সময়সীমা নির্ধারণ করবে।


Guice Scope-এর গুরুত্ব

Guice-এ scopes ব্যবহারের মাধ্যমে আপনি বিভিন্ন ধরনের ডিপেনডেন্সির জীবনচক্র এবং ইনস্ট্যান্স ম্যানেজমেন্টে আরও নিয়ন্ত্রণ পেতে পারেন। এর গুরুত্ব হলো:

1. কার্যকারিতা এবং মেমরি ব্যবস্থাপনা

  • Singleton Scope ব্যবহারের মাধ্যমে আপনি মেমরি ব্যবহার কমাতে পারেন, কারণ একটি ইনস্ট্যান্স একাধিক বার ব্যবহৃত হবে।
  • এর ফলে একাধিক সময় একই ডিপেনডেন্সি তৈরি না হওয়ার কারণে performance optimization হয়।

2. ডিপেনডেন্সি ব্যবস্থাপনা সহজতর

  • Guice Scope ব্যবহার করে আপনি নির্দিষ্ট ডিপেনডেন্সি কখন এবং কিভাবে তৈরি হবে তা নিয়ন্ত্রণ করতে পারবেন।
  • যেমন, ট্রানজেকশন বা সেশন ভিত্তিক ডিপেনডেন্সির জন্য request-scoped ব্যবহার করা যেতে পারে।

3. Testability

  • যখন আপনি scope নির্ধারণ করেন, তখন আপনি সহজেই unit test-এর জন্য mock অবজেক্ট তৈরি করতে পারেন।
  • Singleton Scope বা Custom Scope এর মাধ্যমে সহজেই একাধিক সিচুয়েশনে নির্দিষ্ট স্কোপ অনুযায়ী অবজেক্ট সরবরাহ করতে পারেন।

4. Code Maintainability

  • Scope ব্যবহারের মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা বাড়ানো যায় এবং সহজে কোড মেইনটেইন করা যায়। কারণ আপনি যে scope ব্যবহার করবেন, তার উপর নির্ভর করে প্রতিটি ডিপেনডেন্সি কিভাবে পরিচালিত হবে সেটি পরিষ্কার থাকবে।

সংক্ষেপে

  • Scope Guice-এর মধ্যে Dependency Injection-এর কার্যকারিতা এবং অবজেক্টের জীবনচক্র পরিচালনা করে।
  • Guice-এ প্রধানত তিনটি scope রয়েছে: Singleton, No Scope, এবং Custom Scopes
  • Scope ব্যবহারের মাধ্যমে কোডের কার্যকারিতা, মেমরি ব্যবস্থাপনা, এবং টেস্টেবিলিটি বৃদ্ধি পায়।
Content added By

Guice-এ @Singleton অ্যানোটেশন এবং Singleton Scope ব্যবস্থাপনা গুরুত্বপূর্ণ একটি ধারণা, যা একবার ইনস্ট্যান্স তৈরি করার মাধ্যমে আপনার অ্যাপ্লিকেশনকে দক্ষ এবং কার্যকরী করে তোলে। Singleton Scope ব্যবহার করে নিশ্চিত করা হয় যে একটি নির্দিষ্ট ক্লাসের কেবল একটিমাত্র ইনস্ট্যান্স তৈরি হবে এবং সেটি সারা অ্যাপ্লিকেশনে ব্যবহৃত হবে।

@Singleton Annotation

Guice-এ @Singleton অ্যানোটেশন একটি ক্লাসে ব্যবহৃত হয়, যা নির্দেশ করে যে সেই ক্লাসের কেবল একটি ইনস্ট্যান্স থাকবে এবং সেই ইনস্ট্যান্স পুরো অ্যাপ্লিকেশনে পুনরায় ব্যবহার হবে। এই অ্যানোটেশনটি Singleton Scope নির্ধারণ করতে সাহায্য করে। এটি কার্যকরী যখন আমরা চাই যে কোনো নির্দিষ্ট ক্লাসের একাধিক ইনস্ট্যান্স তৈরি না হয়ে একটিমাত্র ইনস্ট্যান্সই ব্যবহার হোক।

@Singleton Annotation এর ব্যবহার

1. @Singleton অ্যানোটেশন দিয়ে ক্লাস মার্ক করা

import com.google.inject.Singleton;

@Singleton
public class MyService {
    public void execute() {
        System.out.println("Service is executed!");
    }
}

এখানে, @Singleton অ্যানোটেশন MyService ক্লাসের জন্য নিশ্চিত করে যে Guice শুধুমাত্র একটি ইনস্ট্যান্স তৈরি করবে এবং সেই ইনস্ট্যান্স সারা অ্যাপ্লিকেশন জুড়ে ব্যবহার হবে।

2. @Singleton এর সাহায্যে Guice-এ Singleton ইনজেকশন

Guice-এ যখন আপনি @Singleton ব্যবহার করেন, তখন এটি ক্লাসের জন্য সিঙ্গেলটন লাইফসাইকেল পরিচালনা করে। এতে, Guice নিশ্চিত করে যে ক্লাসের একটাই ইনস্ট্যান্স তৈরি হয়, এবং সেটি ইনজেক্ট করা হবে যখনই প্রয়োজন হবে।

import com.google.inject.Guice;
import com.google.inject.Injector;

public class MainApp {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new MyModule());
        MyService service1 = injector.getInstance(MyService.class);
        MyService service2 = injector.getInstance(MyService.class);

        // চেক করুন যদি service1 এবং service2 একই ইনস্ট্যান্স
        System.out.println(service1 == service2);  // Output: true
    }
}

এখানে service1 এবং service2 একই ইনস্ট্যান্স হবে এবং true আউটপুট প্রদান করবে কারণ Guice একটাই ইনস্ট্যান্স তৈরি করেছে এবং এটি সারা অ্যাপ্লিকেশনে শেয়ার করছে।


Singleton Scope ব্যবস্থাপনা

Guice-এ Singleton Scope ম্যানেজ করতে বিভিন্ন পদ্ধতি ব্যবহার করা হয়। @Singleton অ্যানোটেশন ব্যবহার করার পাশাপাশি আপনি in(Singleton.class) মেথডও ব্যবহার করতে পারেন, যা একে সিঙ্গেলটন স্কোপে বাইন্ড করতে সাহায্য করে।

1. in(Singleton.class) ব্যবহার করে Singleton Scope সেট করা

import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(MyService.class).to(MyServiceImpl.class).in(Singleton.class);
    }
}

এখানে, bind(MyService.class).to(MyServiceImpl.class).in(Singleton.class) দিয়ে আপনি MyService-কে MyServiceImpl ক্লাসের সাথে সিঙ্গেলটন স্কোপে বাইন্ড করছেন।

2. @Singleton অ্যানোটেশন এবং in(Singleton.class) এর মধ্যে পার্থক্য

  • @Singleton অ্যানোটেশন: এটি ক্লাসের নিজস্ব সিঙ্গেলটন স্কোপ তৈরি করে এবং Guice-এর জন্য এটি নির্দেশ করে যে একটি ক্লাসের কেবল একটিমাত্র ইনস্ট্যান্স তৈরি করা হবে।
  • in(Singleton.class): এটি AbstractModule বা বাইন্ডিং কনফিগারেশনে ব্যবহার করা হয় এবং Guice-কে বলে যে এই বাইন্ডিংটি সিঙ্গেলটন স্কোপে থাকবে।

এখন, যদি আপনি একই বাইন্ডিংয়ে একাধিক পদ্ধতি ব্যবহার করেন, তবে তারা একে অপরের সাথে মিলে যাবে। যেমন:

import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(MyService.class).to(MyServiceImpl.class);  // Bind MyService to MyServiceImpl
        bind(MyService.class).in(Singleton.class);      // Ensure MyService is a Singleton
    }
}

এক্ষেত্রে Guice শুধুমাত্র একটি ইনস্ট্যান্স তৈরি করবে, এবং এটি সমস্ত স্থানে পুনরায় ব্যবহার করা হবে।


Singleton-এ ডিপেনডেন্সি ইনজেকশন

যখন একটি সিঙ্গেলটন ক্লাসের ডিপেনডেন্সি ইনজেক্ট করতে হয়, তখন Guice নিশ্চিত করে যে সেই ডিপেনডেন্সিও সিঙ্গেলটন হবে।

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class MyService {
    private final MyDatabaseConnection dbConnection;

    @Inject
    public MyService(MyDatabaseConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void execute() {
        dbConnection.connect();
        System.out.println("Service is executed!");
    }
}

@Singleton
public class MyDatabaseConnection {
    public void connect() {
        System.out.println("Database connected!");
    }
}

এখানে, MyService এবং MyDatabaseConnection উভয়ই সিঙ্গেলটন, এবং MyService-এর ডিপেনডেন্সি MyDatabaseConnection-এর একটি একক ইনস্ট্যান্স ব্যবহার করবে।


Guice-এ @Singleton অ্যানোটেশন এবং Singleton Scope ব্যবস্থাপনা ব্যবহারের মাধ্যমে আপনি নিশ্চিত করতে পারেন যে ক্লাসের জন্য কেবল একটি ইনস্ট্যান্স তৈরি হবে এবং সেটি সারা অ্যাপ্লিকেশনে শেয়ার হবে। এটি মেমোরি ব্যবস্থাপনা এবং কর্মক্ষমতা উন্নত করতে সহায়ক, বিশেষত যখন আপনার ক্লাসগুলি একে অপরের উপর নির্ভরশীল হয় এবং আপনি চান না যে বারবার ইনস্ট্যান্স তৈরি হোক। Guice-এর এই কার্যকারিতা আপনার অ্যাপ্লিকেশনে Dependency Injection ব্যবস্থাপনাকে আরও কার্যকর এবং দক্ষ করে তোলে।

Content added By

Guice-এ Custom Scope তৈরি করা মানে এমন একটি scope তৈরি করা যা আপনার প্রয়োজন অনুযায়ী ডিপেনডেন্সির লাইফসাইকেল কন্ট্রোল করতে পারে। Guice-এ ডিফল্টরূপে কিছু স্কোপ যেমন @Singleton বা @Session রয়েছে, কিন্তু আপনি যদি আপনার নির্দিষ্ট প্রয়োজনের জন্য একটি কাস্টম স্কোপ তৈরি করতে চান, তবে Guice তা সহজেই সাপোর্ট করে।

Custom Scope ব্যবহার করলে আপনি ডিপেনডেন্সির ইনস্ট্যান্স সুরক্ষিত করতে পারেন, যাতে সেই ইনস্ট্যান্স একটি নির্দিষ্ট কনটেক্সট বা অবস্থায় (যেমন, থ্রেড, HTTP রিকোয়েস্ট, অথবা অন্য কোন অবস্থান) জীবিত থাকে।

এখানে Custom Scope তৈরি করার প্রক্রিয়া এবং উদাহরণ দেওয়া হলো।


Custom Scope তৈরি করার প্রক্রিয়া

  1. Scope Interface তৈরি করুন: Guice-এ স্কোপ তৈরি করতে আপনাকে একটি কাস্টম স্কোপ ইন্টারফেস তৈরি করতে হবে যা Scope ক্লাসকে ইমপ্লিমেন্ট করবে।
  2. Scope ম্যানেজমেন্ট (Scope Context) তৈরি করুন: Scope কন্টেক্সট ম্যানেজ করার জন্য একটি ক্লাস তৈরি করুন, যেখানে ডিপেনডেন্সির ইনস্ট্যান্স সঞ্চিত থাকবে।
  3. Guice Module-এ কাস্টম স্কোপ যুক্ত করুন: Guice Module-এ আপনি bindScope মেথড ব্যবহার করে কাস্টম স্কোপটি নির্ধারণ করবেন।

Custom Scope উদাহরণ

ধরা যাক, আমরা একটি কাস্টম স্কোপ তৈরি করতে চাই যা একটি নির্দিষ্ট থ্রেডে ডিপেনডেন্সির ইনস্ট্যান্স সাপোর্ট করবে (থ্রেড-স্কোপড ইনজেকশন)।

১. Custom Scope Interface তৈরি করা

প্রথমে একটি ThreadScope নামের কাস্টম স্কোপ ক্লাস তৈরি করুন যা Guice এর Scope ইন্টারফেস ইমপ্লিমেন্ট করবে।

import com.google.inject.Scope;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import java.util.HashMap;
import java.util.Map;

public class ThreadScope implements Scope {

    private static final ThreadLocal<Map<Key<?>, Object>> threadLocalStorage = ThreadLocal.withInitial(HashMap::new);

    @Override
    public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
        return () -> {
            Map<Key<?>, Object> map = threadLocalStorage.get();

            // যদি ইতোমধ্যে ইনস্ট্যান্স থ্রেডে উপস্থিত থাকে তবে তা ফেরত দিন
            if (map.containsKey(key)) {
                return (T) map.get(key);
            }

            // নইলে, নতুন ইনস্ট্যান্স তৈরি করুন এবং তা থ্রেডে সংরক্ষণ করুন
            T instance = unscoped.get();
            map.put(key, instance);
            return instance;
        };
    }

    public static void clear() {
        threadLocalStorage.remove();
    }
}

এই ক্লাসটি থ্রেডস্পেসিফিক স্টোরেজ ব্যবহার করে Provider-এর মাধ্যমে ডিপেনডেন্সি প্রদান করবে। যদি সেই থ্রেডে পূর্বে কোনও ইনস্ট্যান্স সংরক্ষিত থাকে, তবে সেই ইনস্ট্যান্সটি প্রদান করা হবে, নইলে নতুন ইনস্ট্যান্স তৈরি করা হবে এবং সেটি সেই থ্রেডে সংরক্ষণ করা হবে।

২. Module-এ কাস্টম স্কোপ কনফিগার করা

এখন আপনাকে Guice এর Module এ এই স্কোপটি কনফিগার করতে হবে। এটি করার জন্য bindScope মেথড ব্যবহার করতে হবে।

import com.google.inject.AbstractModule;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        // ThreadScope ব্যবহার করা হচ্ছে
        bindScope(ThreadScoped.class, new ThreadScope());
    }
}

৩. Custom Scope অ্যানোটেশন তৈরি করা

Guice-এ স্কোপ কাস্টমাইজ করতে আপনি একটি অ্যানোটেশন তৈরি করতে পারেন। উদাহরণস্বরূপ, ThreadScoped নামের একটি অ্যানোটেশন তৈরি করুন।

import com.google.inject.BindingAnnotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@BindingAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface ThreadScoped {
}

৪. ক্লাসে কাস্টম স্কোপ ব্যবহার করা

এখন আমরা ThreadScoped অ্যানোটেশন ব্যবহার করে আমাদের Service ক্লাসকে কাস্টম স্কোপে যুক্ত করব।

@ThreadScoped
public class ThreadScopedService implements Service {
    private final String id;

    public ThreadScopedService() {
        this.id = "Service instance for Thread: " + Thread.currentThread().getId();
    }

    @Override
    public void serve() {
        System.out.println(id);
    }
}

৫. Guice Injector এবং থ্রেডে ডিপেনডেন্সি ইনজেকশন করা

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AppModule());

        // একটি থ্রেডে ডিপেনডেন্সি ইনজেক্ট করা
        Runnable task = () -> {
            Service service = injector.getInstance(Service.class);
            service.serve();
        };

        // দুইটি থ্রেডে টাস্ক রান করানো
        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);

        thread1.start();
        thread2.start();
    }
}

এখানে, প্রতিটি থ্রেড তার নিজস্ব ThreadScopedService ইনস্ট্যান্স পাবে। যদি দুটি থ্রেড একই Service কনফিগারেশন ব্যবহার করে, তবে তাদের জন্য আলাদা ইনস্ট্যান্স তৈরি হবে।


Guice-এ Custom Scope তৈরি করা Java-তে ডিপেনডেন্সি ইনজেকশনকে আরো ফ্লেক্সিবল এবং কাস্টমাইজেবল করে তোলে। আপনি বিভিন্ন ধরনের স্কোপ তৈরি করতে পারেন যেমন থ্রেড-বেসড, রিকোয়েস্ট-বেসড, এবং আরও অনেক কিছু।

এই উদাহরণে, আমরা থ্রেড-স্পেসিফিক স্কোপ তৈরি করেছি যা প্রতিটি থ্রেডে আলাদা ডিপেনডেন্সি ইনস্ট্যান্স ইনজেক্ট করতে সক্ষম। Guice কাস্টম স্কোপের মাধ্যমে ডিপেনডেন্সি ইনজেকশনকে আরও শক্তিশালী এবং অ্যাডভান্সড তৈরি করা সম্ভব।

Content added By

Guice Dependency Injection Framework এ Eager Singleton এবং Lazy Singleton দুটি বিভিন্ন ধরনের Singleton Scope রয়েছে। এগুলোর মধ্যে মূল পার্থক্য হলো অবজেক্ট ইনস্ট্যান্সিয়েশন এর টাইমিং এবং ডিপেন্ডেন্সি ইনজেকশন পদ্ধতি।

এখানে, আমি Eager Singleton এবং Lazy Singleton এর মধ্যে পার্থক্য ব্যাখ্যা করব।


1. Eager Singleton (Eager Instantiation)

Eager Singleton হল সেই ধরনের সিঙ্গলটন যেখানে অবজেক্টটি তৈরি হয় অ্যাপ্লিকেশন চালু হওয়ার সময় বা মডিউল ইনজেকশন করার সাথে সাথেই। Guice Eager Singleton এর জন্য @Singleton অ্যানোটেশন ব্যবহার করে এবং এটি নিশ্চিত করে যে একবার ক্লাসটি তৈরি হলে সেটি সবসময় একই ইনস্ট্যান্স প্রদান করবে।

বিশেষত্ব:

  • অবজেক্ট তৈরি হয়: অ্যাপ্লিকেশন বা মডিউল লোড হওয়ার সাথে সাথেই।
  • ডিপেন্ডেন্সি ইনজেকশন: একবার ইনস্ট্যান্স তৈরি হয়ে গেলে, পরবর্তী সময়ে পুনরায় তৈরি হয় না।
  • সুবিধা: দ্রুত অ্যাক্সেস এবং ইনস্ট্যান্স গঠন (কোনো বিলম্ব ছাড়াই)।
  • নুকসান: যদি অবজেক্টের ইনস্ট্যান্স প্রয়োজন না থাকে, তবে অযথা রিসোর্স খরচ হতে পারে, কারণ অবজেক্ট আগেই তৈরি হয়ে থাকে।

উদাহরণ:

import com.google.inject.AbstractModule;
import com.google.inject.Singleton;

class Service {
    public Service() {
        System.out.println("Service created");
    }
    public void execute() {
        System.out.println("Executing Service");
    }
}

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Service.class).in(Singleton.class);  // Eager Singleton
    }
}

এখানে, Service ক্লাসটি Eager Singleton হিসেবে বানানো হয়েছে। bind(Service.class).in(Singleton.class); এই কনফিগারেশনটি নিশ্চিত করে যে Service ক্লাসের মাত্র একটিই ইনস্ট্যান্স তৈরি হবে, এবং Guice এটিকে শুরুতেই ইনস্ট্যান্সিয়েট করবে।


2. Lazy Singleton (Lazy Instantiation)

Lazy Singleton হল সেই ধরনের সিঙ্গলটন যেখানে অবজেক্টটি তখনই তৈরি হয় যখন প্রথমবার সেটি প্রয়োজন হয় (মানে লেজি লোডিং)। এখানে, Guice ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে, এবং অবজেক্ট তৈরি করার জন্য Lazy সাপোর্ট থাকে, যেমন Provider<T> ব্যবহার করা হয়।

বিশেষত্ব:

  • অবজেক্ট তৈরি হয়: প্রথমবার ব্যবহার করার সময়।
  • ডিপেন্ডেন্সি ইনজেকশন: একবার অবজেক্ট তৈরি হওয়ার পরে, সেটি পরবর্তী সময়ে আবার তৈরি হবে না।
  • সুবিধা: অবজেক্টের ইন্সট্যান্স কেবল তখনই তৈরি হবে যখন তা সত্যিকার অর্থে প্রয়োজন হয়, যার ফলে অপ্রয়োজনীয় রিসোর্স খরচ কমে।
  • নুকসান: প্রথমবার ইনস্ট্যান্স তৈরি হতে সময় লাগে, কারণ এটি লেট-লোডেড।

উদাহরণ:

import com.google.inject.AbstractModule;
import com.google.inject.Provider;
import com.google.inject.Singleton;

class Service {
    public Service() {
        System.out.println("Service created");
    }
    public void execute() {
        System.out.println("Executing Service");
    }
}

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Service.class).toProvider(ServiceProvider.class).in(Singleton.class);  // Lazy Singleton
    }
}

class ServiceProvider implements Provider<Service> {
    private Service service;

    @Override
    public Service get() {
        if (service == null) {
            service = new Service();  // Lazy Instantiation
        }
        return service;
    }
}

এখানে, Service ক্লাসটি Lazy Singleton হিসেবে তৈরি করা হয়েছে। Provider<T> ব্যবহার করা হয়েছে যাতে সেবা প্রথমবার প্রয়োজন হলে সেটি তৈরি করা হয়। Guice প্রথমবার service.get() কল করলে Service ক্লাসের ইনস্ট্যান্স তৈরি হবে এবং এরপর তা ব্যবহার করা হবে।


Eager Singleton vs Lazy Singleton: পার্থক্য

বৈশিষ্ট্যEager SingletonLazy Singleton
অবজেক্ট ইনস্ট্যান্সিয়েশনঅ্যাপ্লিকেশন বা মডিউল লোড হওয়ার সাথে সাথে।প্রথমবার প্রয়োজন হওয়ার পর।
বিলম্বকোনো বিলম্ব নেই, অবজেক্ট তৈরি হয় তৎক্ষণাৎ।প্রথমবার ব্যবহার করার পর বিলম্ব হয়।
রিসোর্স ব্যবস্থাপনাঅবজেক্ট তৈরি হয় আগেই, প্রয়োজনে না থাকলেও রিসোর্স খরচ হতে পারে।অবজেক্ট তৈরি হয় কেবল তখনই যখন তা প্রয়োজন হয়, রিসোর্স খরচ কম।
ব্যবহারযখন অবজেক্টটি সব সময় ব্যবহৃত হবে।যখন অবজেক্টটি কেবল তখনই ব্যবহৃত হবে যখন তা প্রয়োজন হয়।
সুবিধাদ্রুত অ্যাক্সেস।রিসোর্স দক্ষতা, এবং প্রথমবার লেট-লোডিং।
নুকসানঅপ্রয়োজনীয় রিসোর্স খরচ।প্রথমবার লেট লোডিং হতে পারে।

  • Eager Singleton উপযুক্ত যখন আপনি জানেন যে একটি অবজেক্টের ইনস্ট্যান্স অ্যাপ্লিকেশন চলাকালীন সময়ে সবসময় প্রয়োজন হবে এবং আপনি একে শুরুতেই তৈরি করতে চান।
  • Lazy Singleton উপযুক্ত যখন আপনি নিশ্চিত না যে একটি অবজেক্টের ইনস্ট্যান্সটি পুরো সময়ব্যাপী প্রয়োজন হবে এবং আপনি কেবল তখনই সেটি তৈরি করতে চান যখন সেগুলি প্রকৃতপক্ষে ব্যবহার হবে।

Guice-এ এই দুটি পদ্ধতির মধ্যে নির্বাচন আপনার অ্যাপ্লিকেশনের প্রাকৃতিক প্রয়োজনে নির্ভর করে, এবং যথাযথ নির্বাচন করলে আপনার অ্যাপ্লিকেশন আরও কার্যকর ও রিসোর্স-দক্ষ হবে।

Content added By
Promotion

Are you sure to start over?

Loading...