স্প্রিং ডিপেনডেন্সি ইনজেকশন (DI) এর মাধ্যমে স্প্রিং কনটেইনার Bean এর তৈরি ও ইনস্ট্যান্সিয়েশন প্রক্রিয়াটি নিয়ন্ত্রণ করে। তবে কিছু সময়, আপনি চাইবেন Bean তৈরি হওয়ার পরে বা ইনস্ট্যান্সিয়েশন এবং ইনজেকশনের পর কিছু অতিরিক্ত কাস্টম লজিক প্রয়োগ করতে। এই পরিস্থিতিতে BeanPostProcessor ব্যবহৃত হয়। BeanPostProcessor স্প্রিং ফ্রেমওয়ার্কে একটি ইন্টারফেস যা Bean ইনস্ট্যান্সিয়েশন, ইনজেকশন বা ডেস্ট্রাকশন (ধ্বংস) এর আগে এবং পরে কাস্টম প্রক্রিয়াগুলি প্রয়োগ করতে সহায়তা করে।
BeanPostProcessor এর ব্যবহার
স্প্রিং কনটেইনার Bean তৈরি করার পর, postProcessBeforeInitialization() এবং postProcessAfterInitialization() মেথডগুলো কল করে, যাতে Bean এর ইনিশিয়ালাইজেশন এবং ব্যবহার আগেই অথবা পরে কিছু কাস্টম কোড প্রয়োগ করা যায়।
BeanPostProcessor ইন্টারফেস
BeanPostProcessor ইন্টারফেস দুটি প্রধান মেথড প্রদান করে:
postProcessBeforeInitialization(): Bean ইনস্ট্যান্সিয়েশন এবং প্রোপার্টি ইনজেকশনের পরে, কিন্তু Bean এর@PostConstructবাInitializingBeanইন্টারফেসেরafterPropertiesSet()মেথড কল হওয়ার আগে এটি চালিত হয়।postProcessAfterInitialization(): Bean এর ইনিশিয়ালাইজেশন সম্পন্ন হওয়ার পরে এটি কল হয়, অর্থাৎ Bean এর@PostConstructবাInitializingBeanইন্টারফেসেরafterPropertiesSet()মেথড কল হওয়ার পর।
এগুলো মূলত bean lifecycle এর অংশ, যা কাস্টম লজিক বা অতিরিক্ত কার্যক্রম সম্পাদন করতে সহায়তা করে।
উদাহরণ: BeanPostProcessor ব্যবহার
1. @Component BeanPostProcessor কাস্টম ক্লাস তৈরি করা
ধরা যাক, আপনি চান Bean এর কিছু প্রোপার্টি বা স্টেট পরিবর্তন করতে ইনস্ট্যান্সিয়েশন বা ইনিশিয়ালাইজেশনের পরে।
CustomBeanPostProcessor.java
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// Bean এর ইনিশিয়ালাইজেশন আগে কিছু পরিবর্তন করা
if (bean instanceof EmployeeService) {
System.out.println("Before Initialization of EmployeeService Bean");
}
return bean; // Bean কে রিটার্ন করা, কোন পরিবর্তন না হলে সরাসরি রিটার্ন করা হয়
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// Bean এর ইনিশিয়ালাইজেশন পরে কিছু পরিবর্তন করা
if (bean instanceof EmployeeService) {
System.out.println("After Initialization of EmployeeService Bean");
}
return bean; // Bean কে রিটার্ন করা
}
}
এখানে, CustomBeanPostProcessor একটি কাস্টম BeanPostProcessor যা EmployeeService Bean এর উপর কাজ করে। postProcessBeforeInitialization মেথড কল হওয়ার পরে Bean ইনিশিয়ালাইজেশনের আগে এবং postProcessAfterInitialization মেথড কল হওয়ার পরে Bean এর কিছু কাস্টম লজিক প্রয়োগ করা হয়।
2. Bean কনফিগারেশন এবং @Autowired ইনজেকশন
EmployeeService.java ক্লাসে ইনজেকশন প্রক্রিয়া হবে:
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
private String name;
public EmployeeService() {
this.name = "John Doe";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void printEmployeeDetails() {
System.out.println("Employee Name: " + name);
}
}
এখানে EmployeeService একটি সিম্পল ক্লাস যা name প্রোপার্টি ইনজেক্ট করে এবং printEmployeeDetails মেথডের মাধ্যমে নাম প্রিন্ট করে।
3. Spring Configuration এবং Application Context
AppConfig.java ক্লাসে স্প্রিং কনফিগারেশন করা হবে:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example") // Package এর মধ্যে সব Bean স্বয়ংক্রিয়ভাবে স্ক্যান হবে
public class AppConfig {
}
এখানে, @ComponentScan অ্যানোটেশন স্প্রিং কনটেইনারে ক্লাস গুলো স্ক্যান করবে এবং ইনজেকশন করবে।
4. Main Application Class
এখন, MainApplication.java এ EmployeeService Bean ব্যবহার করা হবে:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApplication {
public static void main(String[] args) {
// Spring container initialization
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// Retrieving bean from container
EmployeeService employeeService = context.getBean(EmployeeService.class);
// Using bean
employeeService.printEmployeeDetails(); // Employee Name: John Doe
context.close();
}
}
এখানে, AnnotationConfigApplicationContext ব্যবহার করে স্প্রিং কনটেইনার তৈরি করা হয়েছে এবং EmployeeService Bean এর printEmployeeDetails() মেথড ব্যবহার করা হয়েছে।
5. BeanPostProcessor প্রক্রিয়া
এখন, আপনার CustomBeanPostProcessor এর মাধ্যমে EmployeeService Bean এর উপর Before এবং After ইনিশিয়ালাইজেশন লজিক প্রয়োগ হবে।
Output:
Before Initialization of EmployeeService Bean
Employee Name: John Doe
After Initialization of EmployeeService Bean
এখানে, Before Initialization মেসেজটি Bean তৈরি হওয়ার আগে প্রিন্ট হবে এবং After Initialization মেসেজটি Bean এর ইনিশিয়ালাইজেশন সম্পন্ন হওয়ার পর প্রিন্ট হবে।
সারাংশ
BeanPostProcessor স্প্রিং ফ্রেমওয়ার্কের একটি শক্তিশালী ইন্টারফেস যা Bean এর Initialization এবং Destruction এর আগে এবং পরে কাস্টম লজিক প্রয়োগ করতে সাহায্য করে। এটি ডিপেনডেন্সি ইনজেকশন বা Bean লাইফসাইকেল পরিচালনার জন্য গুরুত্বপূর্ণ ফিচার। Before এবং After প্রক্রিয়ার মাধ্যমে আপনি Bean এর ইনস্ট্যান্সিয়েশন ও ইনিশিয়ালাইজেশন সম্পন্ন হওয়ার আগেই বা পরে কিছু কার্যক্রম সম্পাদন করতে পারেন। এর মাধ্যমে স্প্রিং কনটেইনারের সাথে আরও সূক্ষ্ম নিয়ন্ত্রণ এবং কাস্টমাইজেশন করা সম্ভব।