Spring Dependency Injection (DI) একটি শক্তিশালী প্যাটার্ন যা স্প্রিং ফ্রেমওয়ার্কে অবজেক্ট ইনস্ট্যান্স এবং তাদের ডিপেনডেন্সি ম্যানেজমেন্ট স্বয়ংক্রিয়ভাবে পরিচালনা করে। যখন একাধিক @Bean এক্সটেনশন বা ক্লাস একই টাইপের ডিপেনডেন্সি প্রদান করে, তখন ডিপেনডেন্সি সিলেকশন কঠিন হয়ে যায়। এই সমস্যা সমাধান করতে @Qualifier অ্যানোটেশন ব্যবহার করা হয়।
এখানে আমরা দেখব কীভাবে Multiple Bean Injection এবং @Qualifier ব্যবহার করা যায় স্প্রিং প্রজেক্টে।
Multiple Bean Injection
স্প্রিং কনটেইনারে একাধিক @Bean একই টাইপের অবজেক্টের জন্য সেবা সরবরাহ করলে, স্প্রিংকে ডিপেনডেন্সি ইনজেকশনের সময় সিদ্ধান্ত নিতে বলা হয় যে কোন একটি অবজেক্ট ব্যবহার করতে হবে। যদি একাধিক @Bean একই টাইপের হয় এবং স্প্রিং কোডে @Autowired ব্যবহার করা হয়, তবে স্প্রিং একটি NoUniqueBeanDefinitionException ত্রুটি ছুঁড়ে দেয়, কারণ স্প্রিং কনটেইনার নিশ্চিত হতে পারে না যে কোন Bean ইনজেক্ট করতে হবে।
এই সমস্যা সমাধানে @Qualifier অ্যানোটেশন ব্যবহার করা হয়, যা স্পষ্টভাবে বলে দেয় কোন নির্দিষ্ট Bean নির্বাচন করতে হবে।
@Qualifier এর ব্যবহার
@Qualifier অ্যানোটেশন স্প্রিং কনটেইনারে ডিপেনডেন্সি ইনজেকশনের জন্য বিশেষ @Bean বা @Component নির্বাচন করতে সাহায্য করে। যখন একাধিক @Bean একই টাইপের হয়, তখন @Qualifier ব্যবহার করে নির্দিষ্ট Bean নির্বাচন করা সম্ভব হয়।
উদাহরণ: Multiple Bean Injection এবং @Qualifier
ধরা যাক, আমাদের একটি GreetingService ইন্টারফেস রয়েছে, এবং আমরা দুটি ভিন্ন ক্লাসের মধ্যে এই ইন্টারফেসের ইনস্ট্যান্স তৈরি করেছি। এখন আমরা @Qualifier ব্যবহার করে সঠিক Bean ইনজেক্ট করব।
Step 1: Service Interface তৈরি করা
public interface GreetingService {
void greet();
}
Step 2: Service Implementation তৈরি করা
// First Implementation of GreetingService
@Component("greetingService1")
public class GreetingServiceImpl1 implements GreetingService {
@Override
public void greet() {
System.out.println("Hello from GreetingServiceImpl1!");
}
}
// Second Implementation of GreetingService
@Component("greetingService2")
public class GreetingServiceImpl2 implements GreetingService {
@Override
public void greet() {
System.out.println("Hello from GreetingServiceImpl2!");
}
}
এখানে, GreetingServiceImpl1 এবং GreetingServiceImpl2 উভয়ই GreetingService ইন্টারফেসের বাস্তবায়ন, এবং প্রতিটি Bean-কে আলাদা নাম দিয়ে @Component অ্যানোটেশন দেওয়া হয়েছে।
Step 3: Client Class তৈরি করা
এখন, Client ক্লাসে আমরা @Qualifier ব্যবহার করে সঠিক GreetingService Bean ইনজেক্ট করব।
@Component
public class Client {
private GreetingService greetingService;
// Constructor Injection with @Qualifier
@Autowired
public Client(@Qualifier("greetingService1") GreetingService greetingService) {
this.greetingService = greetingService;
}
public void showGreeting() {
greetingService.greet();
}
}
এখানে, আমরা @Autowired এর সাথে @Qualifier ব্যবহার করে স্পষ্টভাবে greetingService1 Bean ইনজেক্ট করেছি।
Step 4: Spring Configuration (Java-based)
@Configuration
@ComponentScan("com.example")
public class AppConfig {
@Bean
public Client client() {
return new Client(greetingService1());
}
@Bean
public GreetingService greetingService1() {
return new GreetingServiceImpl1();
}
@Bean
public GreetingService greetingService2() {
return new GreetingServiceImpl2();
}
}
এখানে, AppConfig ক্লাসে আমরা দুইটি GreetingService Bean ডিফাইন করেছি এবং Client Bean-কে ইনস্ট্যান্স তৈরি করতে greetingService1 Bean ইনজেক্ট করেছি।
XML Configuration Example with @Qualifier
Spring XML কনফিগারেশন ফাইলেও @Qualifier অ্যানোটেশন ব্যবহার করা যায়। উদাহরণস্বরূপ:
<bean id="greetingService1" class="com.example.GreetingServiceImpl1"/>
<bean id="greetingService2" class="com.example.GreetingServiceImpl2"/>
<bean id="client" class="com.example.Client">
<constructor-arg ref="greetingService1"/>
</bean>
এখানে, greetingService1 Beanটি Client ক্লাসে ইনজেক্ট করা হয়েছে, যেমনটি Java-based কনফিগারেশন ফাইলে করা হয়েছিল।
Step 5: Main Class
public class MainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Client client = context.getBean(Client.class);
client.showGreeting();
context.close();
}
}
এখানে, Client Bean কনটেইনার থেকে রিট্রিভ করা হয়েছে এবং showGreeting() মেথড কল করা হয়েছে।
@Qualifier এর সুবিধা
- Multiple Bean Injection: একাধিক Bean একই টাইপের থাকলেও,
@Qualifierব্যবহার করে স্পষ্টভাবে কোন Bean ইনজেক্ট করতে হবে তা নির্ধারণ করা যায়। - Clarity: কোডের মধ্যে Bean নির্বাচন পরিষ্কার এবং নির্দিষ্টভাবে প্রদর্শিত হয়।
- Custom Names: Bean নামের মাধ্যমে নির্দিষ্ট
@Componentবা@Beanনির্বাচন করা যায়, যা কোডের রিডেবিলিটি বৃদ্ধি করে।
সারাংশ
Multiple Bean Injection এবং @Qualifier স্প্রিং কনটেইনারে একাধিক Bean থাকলে সঠিক Bean নির্বাচন করতে সাহায্য করে। @Qualifier অ্যানোটেশন দিয়ে আপনি ডিপেনডেন্সি ইনজেকশনের সময় সঠিক Bean নির্বাচন করতে পারেন, যা একাধিক টাইপের Bean থাকলে ত্রুটি এড়াতে সাহায্য করে। এটি স্প্রিং DI-তে কোডের পরিষ্কারতা এবং ডাইনামিকতা আনতে সহায়ক।
Read more