Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যা একটি অবজেক্টকে তার প্রয়োজনীয় ডিপেনডেন্সি (অন্য অবজেক্ট) সরবরাহ (inject) করে, যাতে এই অবজেক্টটি নিজের ডিপেনডেন্সি তৈরি না করে। সহজভাবে বললে, DI হল একটি প্রক্রিয়া যেখানে অবজেক্টটি নিজে থেকে তার ডিপেনডেন্সি তৈরি না করে, বরং অন্য কোনও কম্পোনেন্ট বা কন্টেইনার (যেমন স্প্রিং কন্টেইনার) তার ডিপেনডেন্সি সরবরাহ করে।
স্প্রিং ফ্রেমওয়ার্ক Dependency Injection (DI) প্রক্রিয়া অনুসরণ করে এবং এটি বিভিন্ন অবজেক্টের মধ্যে সম্পর্ক স্থাপন করতে সাহায্য করে, যার ফলে কোডের নমনীয়তা, পুনঃব্যবহারযোগ্যতা, এবং টেস্টযোগ্যতা বৃদ্ধি পায়।
স্প্রিং কনটেইনার DI ব্যবহার করে অবজেক্টগুলির মধ্যে সম্পর্ক তৈরি করে এবং একটি অবজেক্ট যখন অন্য একটি অবজেক্টের উপর নির্ভরশীল হয় তখন সেই নির্ভরশীলতাগুলি কনটেইনার থেকে ইনজেক্ট করা হয়। এই ইনজেকশনটি স্প্রিং কনটেইনারের মাধ্যমে করা হয়, যা অবজেক্টগুলির জীবনচক্র এবং তাদের ডিপেনডেন্সি পরিচালনা করে।
স্প্রিং DI মূলত তিনটি পদ্ধতিতে কাজ করে:
স্প্রিং ফ্রেমওয়ার্কে DI কনফিগার করার জন্য দুটি প্রধান পদ্ধতি রয়েছে:
beans.xml
) ব্যবহার করে ডিপেনডেন্সি ইনজেকশন করা হয়।@Autowired
, @Component
, ইত্যাদি) ব্যবহার করে ডিপেনডেন্সি ইনজেকশন করা হয়।Constructor-based Dependency Injection এ, কোনো অবজেক্টের ডিপেনডেন্সি কনস্ট্রাক্টরের মাধ্যমে ইনজেক্ট করা হয়। এটি সর্বাধিক ব্যবহৃত এবং সুপারিশকৃত পদ্ধতি কারণ এটি অবজেক্ট তৈরির সময় সমস্ত ডিপেনডেন্সি ইনজেক্ট করে এবং আপনি নিশ্চিত হতে পারেন যে অবজেক্টটি সম্পূর্ণভাবে ইনিশিয়ালাইজড।
import org.springframework.stereotype.Component;
@Component
public class Engine {
public void start() {
System.out.println("Engine is starting...");
}
}
@Component
public class Car {
private final Engine engine;
// Constructor-based DI
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving...");
}
}
এখানে:
Car
ক্লাসের কনস্ট্রাক্টর Engine
অবজেক্টকে ইনজেক্ট করে।Engine
অবজেক্টটি Car
ক্লাসে ইনজেক্ট করে।<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="engine" class="com.example.Engine" />
<bean id="car" class="com.example.Car">
<constructor-arg ref="engine" />
</bean>
</beans>
এখানে:
constructor-arg
ট্যাগের মাধ্যমে Engine
অবজেক্টটি Car
এর কনস্ট্রাক্টরে ইনজেক্ট করা হচ্ছে।import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Car {
private final Engine engine;
@Autowired // Constructor-based DI
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving...");
}
}
এখানে:
@Autowired
অ্যানোটেশন দিয়ে কনস্ট্রাক্টরের মাধ্যমে ডিপেনডেন্সি ইনজেক্ট করা হচ্ছে।Setter-based Dependency Injection এ, ডিপেনডেন্সি ইনজেক্ট করার জন্য সেটার মেথড ব্যবহার করা হয়। যদিও এটি একটি সহজ পদ্ধতি, তবে এটি কিছু ক্ষেত্রে কম নিরাপদ হতে পারে, কারণ এটি ঐচ্ছিক (optional) ডিপেনডেন্সি ইনজেকশনকে সমর্থন করে।
import org.springframework.stereotype.Component;
@Component
public class Car {
private Engine engine;
// Setter-based DI
public void setEngine(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving...");
}
}
এখানে:
setEngine()
মেথডের মাধ্যমে Engine
অবজেক্টটি ইনজেক্ট করা হচ্ছে।<bean id="car" class="com.example.Car">
<property name="engine" ref="engine" />
</bean>
এখানে:
property
ট্যাগ ব্যবহার করে Engine
অবজেক্টটি Car
অবজেক্টে ইনজেক্ট করা হচ্ছে।import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Car {
private Engine engine;
@Autowired // Setter-based DI
public void setEngine(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving...");
}
}
এখানে:
@Autowired
অ্যানোটেশন দিয়ে setEngine()
মেথডের মাধ্যমে Engine
অবজেক্ট ইনজেক্ট করা হচ্ছে।Dependency Injection (DI) হল একটি গুরুত্বপূর্ণ ডিজাইন প্যাটার্ন, যা স্প্রিং ফ্রেমওয়ার্কে অবজেক্টের ডিপেনডেন্সিগুলিকে স্বয়ংক্রিয়ভাবে ইনজেক্ট করার পদ্ধতি। স্প্রিং ফ্রেমওয়ার্ক DI এর মাধ্যমে কোডের নমনীয়তা, পুনঃব্যবহারযোগ্যতা, টেস্টযোগ্যতা, এবং রক্ষণাবেক্ষণযোগ্যতা উন্নত করে। DI কনফিগার করার দুটি প্রধান পদ্ধতি হলো XML configuration এবং Annotation-based configuration। Constructor-based এবং Setter-based ইনজেকশন দুটি জনপ্রিয় পদ্ধতি, যেখানে Constructor-based ইনজেকশন সাধারণত সুপারিশকৃত কারণ এটি ডিপেনডেন্সির পূর্ণতা নিশ্চিত করে।
Dependency Injection (DI) হলো একটি ডিজাইন প্যাটার্ন যা অবজেক্ট নির্মাণের সময় তাদের নির্ভরশীলতা (dependencies) বাইরে থেকে সরবরাহ করার প্রক্রিয়া। Spring Framework এ DI এর মাধ্যমে অ্যাপ্লিকেশনের বিভিন্ন ক্লাসের মধ্যে কম্পোনেন্টগুলো (objects) আলাদা করা হয়, এবং প্রয়োজন অনুসারে তাদের ইন্সট্যান্স তৈরির জন্য Spring কন্টেইনার (Spring IoC Container) সাহায্য করে।
Spring DI এর মাধ্যমে, কোনো ক্লাস বা মডিউল তার নির্ভরশীলতা (যেমন অন্যান্য ক্লাস বা অবজেক্ট) সরাসরি নিজের মধ্যে ইনস্ট্যান্সিয়েট না করে, বরং Spring কন্টেইনার তাকে প্রদান করে। এর ফলে কোডের রক্ষণাবেক্ষণ এবং টেস্টিং আরও সহজ হয়ে যায়।
Dependency Injection এর মূল ধারণা হলো:
Spring এ DI সাধারণত Inversion of Control (IoC) কন্টেইনারের মাধ্যমে পরিচালিত হয়, যেখানে Spring কন্টেইনার বিভিন্ন অবজেক্ট বা বীন (bean) তৈরি ও পরিচালনা করে।
Constructor Injection এ, নির্ভরশীল অবজেক্টগুলো কনস্ট্রাক্টর এর মাধ্যমে ইনজেক্ট করা হয়। এই পদ্ধতিতে, যেকোনো ক্লাসের কনস্ট্রাক্টর প্যারামিটার হিসেবে অন্যান্য নির্ভরশীল অবজেক্টগুলো সরবরাহ করা হয়।
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// Constructor Injection
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void getUserDetails() {
// Use userRepository here
}
}
এখানে, UserService
ক্লাসে UserRepository
ইনজেক্ট করা হচ্ছে কনস্ট্রাক্টর এর মাধ্যমে।
Setter Injection এ, নির্ভরশীল অবজেক্টগুলো setter method এর মাধ্যমে ইনজেক্ট করা হয়। Spring কন্টেইনার ক্লাসের setter মেথড কল করে নির্ভরশীলতা সরবরাহ করে।
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private UserRepository userRepository;
// Setter Injection
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void getUserDetails() {
// Use userRepository here
}
}
এখানে, UserService
ক্লাসে UserRepository
ইনজেক্ট করা হচ্ছে setter method এর মাধ্যমে। @Autowired অ্যানোটেশন Spring কন্টেইনারকে জানায় যে, এই setter মেথডটি ব্যবহার করে DI করতে হবে।
Field Injection এ, নির্ভরশীলতা সরাসরি ফিল্ড (instance variable) এ ইনজেক্ট করা হয়। এই পদ্ধতিতে setter বা কনস্ট্রাক্টরের পরিবর্তে Spring কন্টেইনার সরাসরি ফিল্ডে ইনজেক্ট করে।
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // Field Injection
public void getUserDetails() {
// Use userRepository here
}
}
এখানে, UserRepository
সরাসরি userRepository
ফিল্ডে ইনজেক্ট করা হয়েছে @Autowired ব্যবহার করে।
DI ব্যবহারের মাধ্যমে কোডে loose coupling তৈরি হয়, যার মানে হলো ক্লাসগুলোর মধ্যে সম্পর্ক কমানো হয়। এই ধরনের কোডে, একটি ক্লাস তার নির্ভরশীলতা সরাসরি নিজে তৈরি করে না, বরং এগুলি বাইরের উপাদান দ্বারা সরবরাহ করা হয়। এর ফলে কোড আরও নমনীয় এবং রক্ষণাবেক্ষণযোগ্য হয়।
উদাহরণস্বরূপ, যদি একটি ক্লাস নিজে তার নির্ভরশীল অবজেক্ট তৈরি করে, তবে কোডের মডিফিকেশন করলে প্রতিটি ক্লাসে পরিবর্তন করতে হবে। তবে DI ব্যবহারের মাধ্যমে, শুধুমাত্র এক জায়গায় পরিবর্তন করে অন্যান্য অংশে স্বয়ংক্রিয়ভাবে পরিবর্তন আনা সম্ভব হয়।
DI ব্যবহারের মাধ্যমে আপনি unit testing সহজভাবে করতে পারেন। এটি বিভিন্ন অংশের মধ্যে Dependency Injection ব্যবহারের মাধ্যমে মক (mock) অবজেক্ট প্রদান করতে সক্ষম হয়। এর ফলে আপনি বিভিন্ন অবজেক্টের আচরণ আলাদাভাবে পরীক্ষা করতে পারেন।
যেমন:
public class UserServiceTest {
@Test
public void testGetUserDetails() {
UserRepository mockRepo = mock(UserRepository.class);
UserService userService = new UserService(mockRepo);
// Perform tests on userService
}
}
এখানে mock(UserRepository.class)
ব্যবহার করে UserRepository
এর মক অবজেক্ট তৈরি করা হয়েছে, যাতে UserService
টেস্ট করা যায়।
DI ব্যবহারের মাধ্যমে আপনার অ্যাপ্লিকেশনটি আরও রক্ষণাবেক্ষণযোগ্য হয়ে ওঠে। কোনো ক্লাস বা কম্পোনেন্টে পরিবর্তন আনার জন্য, শুধু নির্ভরশীলতা বদলানো হয় এবং অন্য অংশের কোডে কোনো পরিবর্তন করতে হয় না।
DI ব্যবহারের মাধ্যমে আপনি কোডের ফ্লেক্সিবিলিটি বৃদ্ধি করতে পারেন। নির্ভরশীলতা কখনও সহজে পরিবর্তন বা পরীক্ষার জন্য পরিবর্তিত হতে পারে, কারণ বিভিন্ন ধরনের ইমপ্লিমেন্টেশন নির্ভরশীলতা সরবরাহ করা সম্ভব হয়।
DI আপনাকে কোডের দায়িত্ব (concerns) পরিষ্কারভাবে আলাদা করতে সহায়তা করে। এর মাধ্যমে আপনি অ্যাপ্লিকেশনটির বিভিন্ন অংশের কাজ (business logic, database access, UI, etc.) পৃথকভাবে পরিচালনা করতে পারেন।
Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যা কোডের loose coupling নিশ্চিত করে এবং অ্যাপ্লিকেশনকে নমনীয়, টেস্টযোগ্য এবং রক্ষণাবেক্ষণযোগ্য করে তোলে। Spring Framework DI এর মাধ্যমে আপনি ক্লাসগুলির মধ্যে নির্ভরশীলতা স্বয়ংক্রিয়ভাবে ম্যানেজ করতে পারেন, যেমন Constructor Injection, Setter Injection, এবং Field Injection পদ্ধতি ব্যবহারের মাধ্যমে। এর মাধ্যমে আপনার অ্যাপ্লিকেশনের কোড আরও কার্যকরী এবং সহজেই টেস্ট এবং রক্ষণাবেক্ষণযোগ্য হয়।
DI এর প্রয়োগের মাধ্যমে আপনি cross-cutting concerns সহজে এবং মডুলারভাবে পরিচালনা করতে পারেন, যা অ্যাপ্লিকেশন উন্নয়নকে আরও শক্তিশালী এবং স্থিতিশীল করে তোলে।
Spring Framework এর ডিপেনডেন্সি ইনজেকশন (Dependency Injection - DI) একটি গুরুত্বপূর্ণ বৈশিষ্ট্য, যা অবজেক্টগুলির মধ্যে সম্পর্ক পরিচালনা করে এবং তাদের নির্ভরশীলতাগুলি সরবরাহ করে। Spring এ ডিপেনডেন্সি ইনজেকশন করার দুটি প্রধান পদ্ধতি হল Constructor Injection এবং Setter Injection। এই দুটি পদ্ধতির মাধ্যমে আপনি ক্লাসের মধ্যে ডিপেনডেন্সি (অবজেক্টের সম্পর্ক) ইনজেক্ট করতে পারেন।
এই টিউটোরিয়ালে আমরা Constructor Injection এবং Setter Injection এর ব্যবহার এবং তাদের মধ্যে পার্থক্য সম্পর্কে বিস্তারিত আলোচনা করব।
Constructor Injection হল ডিপেনডেন্সি ইনজেকশনের একটি পদ্ধতি যেখানে ডিপেনডেন্সি (অবজেক্ট) ক্লাসের কনস্ট্রাক্টরের মাধ্যমে ইনজেক্ট করা হয়। এই পদ্ধতিতে, Spring কনস্ট্রাক্টরের ইনপুট প্যারামিটারগুলির মাধ্যমে ডিপেনডেন্সি প্রদান করে।
@Component
public class EmployeeService {
private final EmployeeRepository employeeRepository;
// Constructor Injection
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public void saveEmployee(Employee employee) {
employeeRepository.save(employee);
}
}
@Component
public class EmployeeRepository {
public void save(Employee employee) {
System.out.println("Employee saved: " + employee.getName());
}
}
এখানে:
EmployeeRepository
কে ইনজেক্ট করে।EmployeeService
ক্লাসের একটি অবজেক্ট তৈরি করবে, তখন EmployeeRepository
স্বয়ংক্রিয়ভাবে কনস্ট্রাক্টরের মাধ্যমে ইনজেক্ট করা হবে।Spring Configuration (XML/Java Config):
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// Spring automatic DI will work based on constructor injection
}
এখানে, @Component
অ্যানোটেশন দ্বারা Spring জানে যে, এই ক্লাসগুলি Spring Bean হিসেবে ব্যবহার হবে। Spring EmployeeService
এর কনস্ট্রাক্টরকে স্বয়ংক্রিয়ভাবে EmployeeRepository
ইনজেক্ট করবে।
Setter Injection হল ডিপেনডেন্সি ইনজেকশনের আরেকটি পদ্ধতি, যেখানে ডিপেনডেন্সি (অবজেক্ট) ক্লাসের setter method এর মাধ্যমে ইনজেক্ট করা হয়। এই পদ্ধতিতে, আপনি setter methods তৈরি করেন, যেগুলোর মাধ্যমে Spring ডিপেনডেন্সি প্রদান করে।
@Component
public class EmployeeService {
private EmployeeRepository employeeRepository;
// Setter Injection
@Autowired
public void setEmployeeRepository(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public void saveEmployee(Employee employee) {
employeeRepository.save(employee);
}
}
@Component
public class EmployeeRepository {
public void save(Employee employee) {
System.out.println("Employee saved: " + employee.getName());
}
}
এখানে:
EmployeeRepository
ইনজেক্ট করা হয়েছে।Spring Configuration (XML/Java Config):
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// Spring automatic DI will work based on setter injection
}
এখানে, @Autowired
অ্যানোটেশনটি Springকে নির্দেশ দেয় যে এটি ইনজেকশন পয়েন্ট এবং Spring এই setter method এর মাধ্যমে ডিপেনডেন্সি ইনজেক্ট করবে।
বৈশিষ্ট্য | Constructor Injection | Setter Injection |
---|---|---|
মেথড | কনস্ট্রাক্টর মাধ্যমে ইনজেকশন | Setter মেথড মাধ্যমে ইনজেকশন |
ডিপেনডেন্সি | সব ডিপেনডেন্সি আবশ্যক (required dependencies) | কিছু ডিপেনডেন্সি ঐচ্ছিক হতে পারে |
অবজেক্টের পরিবর্তন | একবার ইনজেক্ট করার পর পরিবর্তন করা যায় না | ইনজেকশন পরে ডিপেনডেন্সি পরিবর্তন করা সম্ভব |
কমপ্লেক্সিটি | একটু কমপ্লেক্স (মেথড প্যারামিটার নিতে হবে) | সহজ এবং সহজে পরিবর্তনযোগ্য |
পছন্দের পরিস্থিতি | যখন ডিপেনডেন্সি অপরিহার্য | যখন ডিপেনডেন্সি ঐচ্ছিক বা লেট ইনজেকশন দরকার |
Constructor Injection এবং Setter Injection হল Spring DI (Dependency Injection) এর দুটি গুরুত্বপূর্ণ পদ্ধতি।
Spring Framework এ এই দুটি পদ্ধতি ব্যবহার করে আপনি আপনার ক্লাসের ডিপেনডেন্সিগুলি সরবরাহ করতে পারবেন এবং কার্যকরীভাবে কোডের পুনরাবৃত্তি কমাতে পারবেন।
স্প্রিং ফ্রেমওয়ার্ক একটি শক্তিশালী এবং জনপ্রিয় Java ফ্রেমওয়ার্ক, যা অ্যাপ্লিকেশন ডেভেলপমেন্টে অনেক সুবিধা প্রদান করে। স্প্রিং ফ্রেমওয়ার্কের মূল ধারণাগুলির মধ্যে একটি হল Bean। স্প্রিং Bean এবং এর Lifecycle বুঝতে পারলে স্প্রিং অ্যাপ্লিকেশন ডেভেলপমেন্ট আরও কার্যকরী এবং নিয়ন্ত্রিত হয়।
স্প্রিং ফ্রেমওয়ার্কে, Bean হল একটি অবজেক্ট যা স্প্রিং কনটেইনার (ApplicationContext বা BeanFactory) দ্বারা তৈরি, কনফিগার এবং ম্যানেজ করা হয়। স্প্রিং Bean হল সেই সমস্ত ক্লাস বা অবজেক্ট, যেগুলো স্প্রিং কনটেইনারের মাধ্যমে ইনস্ট্যান্সিয়েটেড, কনফিগার এবং ম্যানেজ করা হয়। স্প্রিং কনটেইনার একটি IoC (Inversion of Control) কনটেইনার, যা ডিপেন্ডেন্সি ইনজেকশন (DI) পরিচালনা করে এবং অবজেক্টের লাইফ সাইকেল পরিচালনা করে।
স্প্রিং Bean সাধারণত নিম্নলিখিতভাবে কনফিগার করা হয়:
<bean>
ট্যাগ ব্যবহার করে Bean কনফিগার করা হয়।@Component
public class EmployeeService {
public void addEmployee() {
System.out.println("Employee added!");
}
}
এখানে, EmployeeService
ক্লাসটি একটি স্প্রিং Bean হিসেবে কনফিগার করা হয়েছে, কারণ এটি @Component
অ্যানোটেশন ব্যবহার করেছে। স্প্রিং কনটেইনার এই Bean কে নিজেই ইনস্ট্যান্সিয়েট করবে এবং ব্যবহারের জন্য প্রস্তুত রাখবে।
স্প্রিং Bean এর Lifecycle হল একটি Bean এর সৃষ্টি থেকে ধ্বংস হওয়া পর্যন্ত যে সমস্ত পর্যায় অতিক্রম করে, তা বোঝানোর প্রক্রিয়া। স্প্রিং কনটেইনার একটি Bean এর lifecycle নিয়ন্ত্রণ করে, যাতে Bean এর অবস্থা পর্যায়ক্রমে পরিবর্তিত হয়।
স্প্রিং Bean Lifecycle এর গুরুত্বপূর্ণ পর্যায়গুলি হল:
@Component
, @Service
, @Repository
, @Controller
অ্যানোটেশন বা XML কনফিগারেশন দ্বারা নির্ধারিত হয়।@PostConstruct
অ্যানোটেশন বা InitializingBean ইন্টারফেসের মাধ্যমে এই কাজগুলো করে থাকে।@PostConstruct
অ্যানোটেশন থাকে, তখন সেই মেথডটি কল করা হয়।afterPropertiesSet()
মেথডটি কল করা হবে।@PreDestroy
অ্যানোটেশন বা DisposableBean ইন্টারফেসের মাধ্যমে ধ্বংসের জন্য নির্দিষ্ট মেথড কল করা হয়।@PreDestroy
অ্যানোটেশন ব্যবহার করা যেতে পারে।@Component
public class EmployeeService implements InitializingBean, DisposableBean {
public void addEmployee() {
System.out.println("Employee added!");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("EmployeeService Bean initialized!");
}
@Override
public void destroy() throws Exception {
System.out.println("EmployeeService Bean destroyed!");
}
}
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// Retrieve Bean from the context
EmployeeService employeeService = context.getBean(EmployeeService.class);
// Use the Bean
employeeService.addEmployee();
// Close context to trigger destruction
context.close();
}
}
EmployeeService Bean initialized!
Employee added!
EmployeeService Bean destroyed!
এখানে, afterPropertiesSet() এবং destroy() মেথডগুলি Bean এর লাইফসাইকেলের মধ্যে ইনিশিয়ালাইজেশন এবং ধ্বংসের সময় কার্যকর হয়েছে।
স্প্রিং Bean এর ইনিশিয়ালাইজেশন এবং ধ্বংস প্রক্রিয়া সহজ করার জন্য @PostConstruct এবং @PreDestroy অ্যানোটেশন ব্যবহার করা যায়।
@Component
public class EmployeeService {
public void addEmployee() {
System.out.println("Employee added!");
}
@PostConstruct
public void init() {
System.out.println("EmployeeService Bean initialized!");
}
@PreDestroy
public void destroy() {
System.out.println("EmployeeService Bean destroyed!");
}
}
এখানে, @PostConstruct এবং @PreDestroy অ্যানোটেশনগুলো Bean এর লাইফসাইকেলের ইনিশিয়ালাইজেশন এবং ধ্বংস পর্যায়ে কার্যকর হবে।
স্প্রিং Bean-এর লাইফসাইকেল বিভিন্ন স্কোপে পরিচালিত হতে পারে। স্প্রিং ফ্রেমওয়ার্কে প্রধানত পাঁচটি Bean Scope থাকে:
@Bean
@Scope("singleton") // or "prototype", "request", "session", "application"
public EmployeeService employeeService() {
return new EmployeeService();
}
স্প্রিং Bean এবং Bean Lifecycle স্প্রিং কনটেইনারের দ্বারা পরিচালিত হয় এবং এটি কোডের কার্যকারিতা এবং রক্ষণাবেক্ষণ সহজ করতে সহায়তা করে। স্প্রিং Bean এর লাইফসাইকেল সম্পর্কে জানলে আপনি স্প্রিং এর উপর নির্ভরশীল অ্যাপ্লিকেশনকে আরো দক্ষতার সাথে কনফিগার এবং ম্যানেজ করতে পারবেন। Bean Lifecycle এর অন্তর্গত Initialization, Dependency Injection, Post-Initialization, এবং Destruction পর্যায়গুলো নিশ্চিত করে যে, Bean তার নির্দিষ্ট কাজ সঠিকভাবে করবে এবং কনটেইনারে তার প্রয়োজনীয় রিসোর্স মুক্ত হবে।
Dependency Injection (DI) হলো একটি ডিজাইন প্যাটার্ন, যা স্প্রিং ফ্রেমওয়ার্কের মূল বৈশিষ্ট্যগুলোর মধ্যে একটি। DI-এর মাধ্যমে একটি ক্লাসের নির্ভরশীলতাগুলো (Dependencies) তার বাইরের কোনো উৎস থেকে ইনজেক্ট করা হয়, ফলে কোডটি ডিকাপলড (Decoupled) এবং মডুলার হয়।
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.0</version>
</dependency>
@Component
public class EmployeeRepository {
public String fetchEmployeeData() {
return "Employee Data from Database";
}
}
@Component
public class EmployeeService {
private final EmployeeRepository employeeRepository;
// Constructor Injection
@Autowired
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public void displayEmployeeData() {
String data = employeeRepository.fetchEmployeeData();
System.out.println("Service Layer: " + data);
}
}
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// DI এর মাধ্যমে EmployeeService Bean পাওয়া
EmployeeService employeeService = context.getBean(EmployeeService.class);
employeeService.displayEmployeeData();
context.close();
}
}
Service Layer: Employee Data from Database
@Component
public class EmployeeService {
private EmployeeRepository employeeRepository;
// Setter Injection
@Autowired
public void setEmployeeRepository(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public void displayEmployeeData() {
String data = employeeRepository.fetchEmployeeData();
System.out.println("Service Layer: " + data);
}
}
@Component
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public void displayEmployeeData() {
String data = employeeRepository.fetchEmployeeData();
System.out.println("Service Layer: " + data);
}
}
স্প্রিং ফ্রেমওয়ার্কে DI একটি গুরুত্বপূর্ণ ফিচার যা কোডের Coupling কমায় এবং রিইউজেবিলিটি বাড়ায়। Constructor Injection সাধারণত সেরা পদ্ধতি হিসেবে বিবেচিত হয়, তবে নির্ভরশীলতার প্রয়োজন অনুযায়ী Setter এবং Field Injectionও ব্যবহৃত হতে পারে।
Read more