MapStruct একটি Java ভিত্তিক মডেল ম্যাপিং টুল যা compile-time এ কোড জেনারেট করে এবং ডোমেইন অবজেক্টগুলির মধ্যে ডেটা ম্যাপিং করতে সাহায্য করে। এটি সাধারণত JavaBeans (POJOs) এবং DTO (Data Transfer Object) এর মধ্যে ম্যাপিং করতে ব্যবহৃত হয়। Spring Framework একটি শক্তিশালী এবং জনপ্রিয় ফ্রেমওয়ার্ক যা Java এ এন্টারপ্রাইজ অ্যাপ্লিকেশন ডেভেলপমেন্টে ব্যবহৃত হয়। MapStruct এবং Spring এর একত্রিত ব্যবহার ডেটা ম্যাপিং প্রক্রিয়া আরও সহজ এবং কার্যকরী করে তোলে।
MapStruct এবং Spring Integration এ আমরা আলোচনা করব কিভাবে MapStruct কে Spring Bean হিসেবে কনফিগার করে এবং Spring প্রোজেক্টে এটি ব্যবহার করা যায়।
১. MapStruct এবং Spring Integration এর প্রয়োজনীয়তা
Spring এ MapStruct ব্যবহার করার প্রধান সুবিধা হলো স্বয়ংক্রিয়ভাবে Bean Injection এবং Dependency Injection এর মাধ্যমে সহজে ম্যাপিং কোডের ব্যবহার করা। MapStruct Spring Bean হিসেবে কাজ করতে সক্ষম, যার মাধ্যমে ডেটা ট্রান্সফার অবজেক্ট (DTO) এবং ডোমেইন অবজেক্টের মধ্যে ম্যাপিং অটোমেটিক্যালি পরিচালিত হতে পারে।
Spring এর মধ্যে MapStruct ইন্টিগ্রেট করার জন্য আপনাকে কিছু কনফিগারেশন করতে হবে, যাতে MapStruct এর Mapper Interface গুলো Spring Beans হিসেবে কাজ করে।
২. MapStruct Spring Integration Setup
Spring এর মধ্যে MapStruct ব্যবহারের জন্য, আপনাকে MapStruct এর Mapper Interface গুলিকে Spring Beans হিসেবে কনফিগার করতে হবে। এটি করতে হলে আপনাকে componentModel = "spring" কনফিগারেশন ব্যবহার করতে হবে। এর ফলে MapStruct আপনার Mapper Interface গুলিকে Spring Bean হিসেবে চিহ্নিত করবে এবং Spring Framework এগুলো ইনজেক্ট করবে।
Step-by-step Spring Integration
Maven Dependency Configuration
প্রথমে, MapStruct এবং Spring Integration এর জন্য Maven ডিপেনডেন্সি যুক্ত করুন।
<dependencies> <!-- MapStruct Dependency --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.2.Final</version> </dependency> <!-- MapStruct Processor Dependency --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.2.Final</version> <scope>provided</scope> </dependency> <!-- Spring Boot Dependency (if using Spring Boot) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>MapStruct Mapper Interface Configuration
MapStruct Mapper Interface তৈরি করতে হবে যেখানে আপনি ডোমেইন অবজেক্ট থেকে DTO অবজেক্টে ম্যাপিং করতে চান। এখানে
componentModel = "spring"ব্যবহার করবেন, যা MapStruct কে Spring Bean হিসেবে কনফিগার করতে সহায়তা করবে।import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @Mapper(componentModel = "spring") public interface PersonMapper { PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class); PersonDTO personToPersonDTO(Person person); }এখানে,
componentModel = "spring"কনফিগারেশন দেওয়া হয়েছে, যার ফলে PersonMapper Spring Bean হিসেবে কাজ করবে।Spring Service Class
একবার MapStruct Mapper প্রস্তুত হলে, Spring Service ক্লাসে আপনি এটি ইনজেক্ট করতে পারেন। @Autowired অ্যানোটেশন ব্যবহার করে আপনার Mapper ইন্টারফেসকে ইনজেক্ট করা যাবে।
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonService { private final PersonMapper personMapper; @Autowired public PersonService(PersonMapper personMapper) { this.personMapper = personMapper; } public PersonDTO convertToDTO(Person person) { return personMapper.personToPersonDTO(person); } }এখানে, PersonService ক্লাসে PersonMapper কে ইনজেক্ট করা হয়েছে এবং
convertToDTOমেথডের মাধ্যমে Person অবজেক্টকে PersonDTO তে রূপান্তর করা হচ্ছে।
৩. Spring Boot Integration Example
Spring Boot প্রোজেক্টে MapStruct এর ইন্টিগ্রেশন আরও সহজ। Spring Boot প্রোজেক্টে আপনি MapStruct কে Spring Bean হিসেবে ব্যবহার করতে পারেন এবং এটি সঠিকভাবে কার্যকরী হবে।
উদাহরণ: Spring Boot প্রোজেক্টের মধ্যে MapStruct ব্যবহার
Spring Boot Starter Dependency
প্রথমে, spring-boot-starter ডিপেনডেন্সি pom.xml ফাইলে যুক্ত করুন, যদি এটি আপনার প্রোজেক্টে না থাকে।
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>Spring Boot Application Class
Spring Boot অ্যাপ্লিকেশন ক্লাস তৈরির জন্য @SpringBootApplication অ্যানোটেশন ব্যবহার করুন এবং main মেথডে SpringApplication.run() কল করুন।
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }Controller Class
Spring Boot অ্যাপ্লিকেশন তৈরি হলে, আপনার Controller ক্লাসে PersonService ব্যবহার করতে পারবেন।
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class PersonController { private final PersonService personService; @Autowired public PersonController(PersonService personService) { this.personService = personService; } @GetMapping("/convert") public PersonDTO convertPerson(@RequestParam String name, @RequestParam int age) { Person person = new Person(name, age); return personService.convertToDTO(person); } }এখানে, PersonController ক্লাসে
convertPersonএন্ডপয়েন্ট তৈরি করা হয়েছে, যা Person অবজেক্ট গ্রহণ করে এবং PersonDTO তে রূপান্তরিত করে।
৪. MapStruct এবং Spring এর সাথে সুবিধা
- Spring Bean Integration:
componentModel = "spring"ব্যবহার করে আপনার MapStruct Mapper ইন্টারফেসকে Spring Bean হিসেবে সহজে ব্যবহার করা যায়। - Dependency Injection: Spring এর @Autowired অ্যানোটেশন ব্যবহার করে আপনি সহজে Mapper ইন্টারফেস ইনজেক্ট করতে পারেন।
- Compile-time Code Generation: MapStruct compile-time এ কোড জেনারেট করে, যা পারফরম্যান্সে উপকারী এবং runtime এ কোন অবাঞ্ছিত অতিরিক্ত লোড সৃষ্টি হয় না।
- Custom Mapping Logic: আপনি কাস্টম ম্যাপিং এবং কনভার্সন লজিক ব্যবহার করতে পারেন।
- Spring Boot Compatible: Spring Boot প্রোজেক্টে এটি সহজেই ইন্টিগ্রেট করা যায় এবং Spring Bean হিসেবে ম্যাপিং প্রক্রিয়া সম্পন্ন করা যায়।
সারাংশ
MapStruct এবং Spring Integration মডেল ম্যাপিং প্রক্রিয়াকে দ্রুত এবং সহজ করে তোলে। MapStruct ব্যবহার করে আপনি compile-time কোড জেনারেশন করতে পারেন, যা পারফরম্যান্সে সুরক্ষা প্রদান করে। Spring এর সাথে ইন্টিগ্রেট করার জন্য আপনাকে componentModel = "spring" কনফিগারেশন ব্যবহার করতে হবে, যার ফলে MapStruct এর Mapper ইন্টারফেস গুলো Spring Bean হিসেবে কাজ করবে। এই ধরনের ইন্টিগ্রেশন ডেটা ট্রান্সফার অবজেক্ট (DTO) এবং ডোমেইন অবজেক্টের মধ্যে কার্যকরী ম্যাপিং সরবরাহ করে।
MapStruct একটি Java annotation processor ভিত্তিক মডেল ম্যাপিং টুল যা সহজে ডোমেইন অবজেক্ট থেকে DTO (Data Transfer Object) বা অন্য মডেল অবজেক্টে ডেটা ট্রান্সফার করতে ব্যবহৃত হয়। এটি কম্পাইল-টাইম কোড জেনারেশন ব্যবহার করে এবং রানটাইম পারফরম্যান্সের উপর কোনো নেতিবাচক প্রভাব ফেলে না।
Spring Framework এর সাথে MapStruct ইন্টিগ্রেশন করা খুবই সহজ এবং এটি Spring Beans হিসেবে মডেল ম্যাপিং ফাংশনকে ব্যবহারের সুযোগ দেয়। Spring এবং MapStruct এর সংমিশ্রণ সিস্টেমে ডেটা ম্যাপিং প্রক্রিয়া সহজ, দ্রুত এবং টাইপ সেফ হতে সহায়তা করে।
এই গাইডে, আমরা দেখব MapStruct কীভাবে Spring Framework এর সাথে ইন্টিগ্রেট করা হয়, এবং একটি উদাহরণসহ MapStruct এর ম্যাপিং ফাংশন Spring Bean হিসেবে কীভাবে কাজ করে।
১. MapStruct এবং Spring Integration এর জন্য প্রয়োজনীয় ডিপেনডেন্সি
Spring Framework এর সাথে MapStruct ব্যবহারের জন্য আপনাকে কিছু নির্দিষ্ট ডিপেনডেন্সি pom.xml (Maven) বা build.gradle (Gradle) ফাইলে যুক্ত করতে হবে।
Maven Dependency:
<dependencies>
<!-- MapStruct Dependency -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<!-- MapStruct Processor Dependency for compile-time code generation -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- Spring Boot Dependency (if using Spring Boot) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Gradle Dependency:
dependencies {
implementation 'org.mapstruct:mapstruct:1.5.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.2.Final'
// Spring Boot dependency (if using Spring Boot)
implementation 'org.springframework.boot:spring-boot-starter'
}
এখানে, mapstruct এবং mapstruct-processor ডিপেনডেন্সি মূল MapStruct কার্যকারিতা এবং annotation processor কোড জেনারেট করতে সাহায্য করে। এবং spring-boot-starter Spring Boot প্রোজেক্টে ব্যবহৃত হয়।
২. MapStruct এবং Spring Integration এর জন্য Configuration
MapStruct কে Spring Framework এর সাথে ইন্টিগ্রেট করতে, আপনাকে componentModel = "spring" কনফিগারেশন ব্যবহার করতে হবে। এটি MapStruct কে Spring Bean হিসেবে কনফিগার করবে এবং Spring এর মধ্যে স্বয়ংক্রিয়ভাবে ইনজেক্ট হবে।
উদাহরণ: Spring Integration with MapStruct
Person.java (Domain Object):
public class Person {
private String firstName;
private String lastName;
// Getters and Setters
}
PersonDTO.java (DTO):
public class PersonDTO {
private String fullName;
// Getters and Setters
}
PersonMapper.java (MapStruct Mapper Interface):
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(componentModel = "spring") // Spring Bean হিসেবে ইনজেক্ট করা হবে
public interface PersonMapper {
@Mapping(source = "firstName", target = "fullName")
PersonDTO personToPersonDTO(Person person);
}
এখানে, componentModel = "spring" ব্যবহার করা হয়েছে, যা MapStruct কে Spring Bean হিসেবে কনফিগার করে।
৩. Spring Service Layer এ MapStruct ব্যবহার
Spring Framework এর মধ্যে MapStruct এর মেথড ইনজেক্ট করতে, আপনাকে শুধু @Autowired ব্যবহার করতে হবে। নিচে একটি Spring Service লেয়ার উদাহরণ দেওয়া হলো।
PersonService.java (Spring Service):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
private final PersonMapper personMapper;
@Autowired
public PersonService(PersonMapper personMapper) {
this.personMapper = personMapper;
}
public PersonDTO convertToDTO(Person person) {
return personMapper.personToPersonDTO(person);
}
}
এখানে, PersonMapper ইন্টারফেসটি Spring Bean হিসেবে ইনজেক্ট করা হচ্ছে এবং convertToDTO মেথডে MapStruct এর মাধ্যমে Person অবজেক্ট থেকে PersonDTO তে ডেটা ম্যাপ করা হচ্ছে।
৪. Spring Boot Controller এ MapStruct ব্যবহার
Spring Boot Controller তে MapStruct ব্যবহার করতে, আপনি PersonService কে ইনজেক্ট করতে পারেন এবং REST API এর মাধ্যমে ডেটা ম্যাপিং করতে পারেন।
PersonController.java (Spring Boot Controller):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PersonController {
private final PersonService personService;
@Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}
@GetMapping("/person")
public PersonDTO getPersonDTO() {
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
return personService.convertToDTO(person);
}
}
এখানে, PersonController PersonService কে ইনজেক্ট করে এবং একটি GET রিকোয়েস্টের মাধ্যমে Person অবজেক্ট থেকে PersonDTO তে ডেটা ম্যাপিং করে রিটার্ন করছে।
৫. MapStruct এবং Spring Boot Application Example
Spring Boot Application এর মধ্যে MapStruct ব্যবহার করলে আপনার কোড আরও পরিষ্কার, দ্রুত এবং রক্ষণাবেক্ষণযোগ্য হয়। Spring Boot এর @SpringBootApplication অ্যানোটেশন দিয়ে Spring Boot অ্যাপ্লিকেশন চালু করতে পারেন।
Application.java (Spring Boot Main Class):
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
এখানে, @SpringBootApplication অ্যানোটেশন Spring Boot অ্যাপ্লিকেশন শুরু করার জন্য ব্যবহৃত হয়।
৬. MapStruct এর প্রধান সুবিধা
- Compile-time code generation: MapStruct compile-time এ কোড জেনারেট করে, যা রানটাইম পারফরম্যান্সের উপর কোনো প্রভাব ফেলে না।
- Spring Integration: Spring Framework এর সাথে সহজে ইন্টিগ্রেট করা যায়, এবং Spring Bean হিসেবে কাজ করতে পারে।
- Custom Mappings: MapStruct কাস্টম ম্যাপিং এর সুবিধা দেয়, যেমন কাস্টম কনভার্সন লজিক, এনাম (enum) ম্যাপিং ইত্যাদি।
- Type Safety: এটি টাইপ সেফটি প্রদান করে, ফলে টাইপ মিসম্যাচের কারণে ত্রুটি কম হয়।
- Ease of Use: MapStruct খুবই সহজ, এবং আপনি কেবলমাত্র মেথড সিগনেচার তৈরি করেন, অন্যসব কাজ MapStruct কোড জেনারেট করে।
সারাংশ
MapStruct এবং Spring Framework এর সংমিশ্রণ আপনাকে দ্রুত, সহজ এবং টাইপ সেফ ডেটা ম্যাপিং সমাধান প্রদান করে। MapStruct কোড জেনারেট করার মাধ্যমে আপনাকে ডোমেইন অবজেক্ট থেকে DTO বা অন্য মডেল অবজেক্টে ম্যাপিং করতে সহায়তা করে, এবং Spring এর সাথে একত্রে এটি আরও সহজ হয়ে ওঠে। MapStruct কে Spring Bean হিসেবে কনফিগার করার জন্য componentModel = "spring" ব্যবহার করা হয়, এবং Spring Services এবং Controllers এ সহজেই এই ম্যাপিং ব্যবহার করা যায়।
MapStruct একটি শক্তিশালী Java annotation processor ভিত্তিক লাইব্রেরি যা compile-time এ ম্যাপিং কোড জেনারেট করে। এটি JavaBeans বা POJOs (Plain Old Java Objects) এর মধ্যে ম্যাপিং করতে ব্যবহৃত হয় এবং ডেটা ট্রান্সফার অবজেক্ট (DTO) বা ডোমেইন অবজেক্টের মধ্যে ডেটা এক্সচেঞ্জ সহজ করে তোলে। MapStruct এর সুবিধা হলো, এটি compile-time এ কোড জেনারেট করে, তাই রানটাইম পারফরম্যান্সের উপর কোনো নেতিবাচক প্রভাব পড়ে না।
Spring ফ্রেমওয়ার্কের সাথে MapStruct ইন্টিগ্রেট করা খুবই সহজ এবং এটি Spring Beans এবং Dependency Injection (DI) এর মাধ্যমে আরো কার্যকরী হয়ে ওঠে। এই টিউটোরিয়ালে, আমরা MapStruct এর মাধ্যমে Spring Bean Mapping এবং Dependency Injection কিভাবে কাজ করে তা উদাহরণসহ দেখব।
১. MapStruct এবং Spring Integration
Spring Framework এর সাথে MapStruct ইন্টিগ্রেট করার জন্য, আপনাকে Mapper ইন্টারফেসে componentModel = "spring" কনফিগারেশন ব্যবহার করতে হবে। এর মাধ্যমে MapStruct Spring Beans তৈরি করে এবং Spring এর Dependency Injection (DI) ব্যবহারের মাধ্যমে Mapper Beans ইনজেক্ট করা যায়।
উদাহরণ: Spring Integration
Person.java (Domain Object):
public class Person {
private String name;
private int age;
// Getters and Setters
}
PersonDTO.java (DTO):
public class PersonDTO {
private String name;
private int age;
// Getters and Setters
}
PersonMapper.java (Mapper Interface with Spring Integration):
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
PersonDTO personToPersonDTO(Person person);
}
এখানে, componentModel = "spring" যুক্ত করার মাধ্যমে PersonMapper ইন্টারফেসটি Spring Bean হিসাবে কনফিগার করা হয়েছে।
২. Spring Bean Dependency Injection এর ব্যবহার
এখন, আপনি Spring কনটেক্সটে এই Mapper ইন্টারফেস ব্যবহার করতে পারেন। Spring এর Dependency Injection ব্যবহারের মাধ্যমে MapStruct Mapper সহজেই Spring Beans হিসাবে ইনজেক্ট করা যেতে পারে।
PersonService.java (Spring Service Class):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
private final PersonMapper personMapper;
@Autowired
public PersonService(PersonMapper personMapper) {
this.personMapper = personMapper;
}
public PersonDTO convertPersonToDTO(Person person) {
return personMapper.personToPersonDTO(person);
}
}
এখানে, @Autowired অ্যানোটেশন ব্যবহার করে PersonMapper ইনজেক্ট করা হয়েছে। Spring স্বয়ংক্রিয়ভাবে PersonMapper Bean ইনজেক্ট করবে, কারণ এটি componentModel = "spring" ব্যবহার করে Spring Bean হিসাবে কনফিগার করা হয়েছে।
৩. Spring Boot Application Setup
আপনার Spring Boot অ্যাপ্লিকেশন কনফিগারেশন করতে, আপনি @SpringBootApplication এবং @ComponentScan ব্যবহার করতে পারেন, যাতে Spring ফ্রেমওয়ার্ক সমস্ত Bean সঠিকভাবে স্ক্যান এবং ইনজেক্ট করতে পারে।
Application.java (Main Application Class):
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Boot অ্যাপ্লিকেশন চালানোর সময়, PersonMapper Bean স্বয়ংক্রিয়ভাবে Spring কনটেক্সটে ইনজেক্ট হবে এবং আপনি PersonService ক্লাসের মাধ্যমে Mapper ফাংশন ব্যবহার করতে পারবেন।
৪. Spring Bean Mapping ব্যবহার করার সুবিধা
- Automatic Dependency Injection: Spring Framework এর মাধ্যমে Mapper Bean গুলি স্বয়ংক্রিয়ভাবে ইনজেক্ট হয়, যাতে ডেভেলপারের কোনো ম্যানুয়াল ইনজেকশন প্রয়োজন হয় না।
- Modular Design: Spring এবং MapStruct এর সংমিশ্রণ আপনার অ্যাপ্লিকেশনকে আরও মডুলার করে তোলে। আপনার ডোমেইন অবজেক্টের পরিবর্তন প্রভাবিত না করে ডেটা ট্রান্সফার অবজেক্টগুলি (DTOs) খুব সহজেই অ্যাডজাস্ট করা যায়।
- Code Reusability: Spring Bean Mapping ব্যবহার করলে আপনি আপনার Mapper ইন্টারফেসটি পুনরায় ব্যবহার করতে পারেন বিভিন্ন জায়গায়, এবং এটি একত্রিত করা সহজ হয়।
- Separation of Concerns: Spring Beans এবং MapStruct এর মাধ্যমে অ্যাপ্লিকেশনের লজিক এবং ডেটা ম্যাপিং আলাদা রাখা যায়, যা কোড রিয়ুসেবিলিটি এবং মেনটেনেন্স সহজ করে।
৫. MapStruct এবং Spring এর মধ্যে ডিপেনডেন্সি ইনজেকশন
Spring Dependency Injection (DI) এর মাধ্যমে আপনি সহজেই Mapper Beans বা অন্যান্য Beans ইনজেক্ট করতে পারেন। এতে আপনাকে Mapper ইন্টারফেস বা অটোমেটিক ম্যাপিং কোডের জন্য আলাদা ক্লাস তৈরি করার প্রয়োজন পড়ে না। Spring Bean হিসেবে ব্যবহৃত Mapper গুলি @Autowired অ্যানোটেশন দ্বারা স্বয়ংক্রিয়ভাবে ইনজেক্ট হয়ে যায়।
উদাহরণ: Main.java (Spring Controller Example)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PersonController {
private final PersonService personService;
@Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}
@GetMapping("/convert")
public PersonDTO getPersonDTO(@RequestParam String name, @RequestParam int age) {
Person person = new Person();
person.setName(name);
person.setAge(age);
return personService.convertPersonToDTO(person);
}
}
এখানে, PersonController ক্লাসে PersonService ইনজেক্ট করা হয়েছে এবং Spring Boot এর মাধ্যমে PersonDTO এর মান কনভার্ট করা হচ্ছে।
৬. MapStruct এবং Spring Boot Testing
Spring Boot Testing এর মাধ্যমে আপনি MapStruct মেপার ফাংশন এবং ইনজেকশন প্রক্রিয়াগুলিকে সহজেই টেস্ট করতে পারেন। @SpringBootTest ব্যবহার করে আপনার অ্যাপ্লিকেশন টেস্ট করা যায়।
উদাহরণ: PersonServiceTest.java (JUnit Test)
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class PersonServiceTest {
@Autowired
private PersonService personService;
@Test
public void testPersonMapping() {
Person person = new Person();
person.setName("John");
person.setAge(30);
PersonDTO personDTO = personService.convertPersonToDTO(person);
assertEquals("John", personDTO.getName());
assertEquals(30, personDTO.getAge());
}
}
এখানে, @SpringBootTest এর মাধ্যমে PersonService ইনজেক্ট করা হয়েছে এবং Person অবজেক্ট থেকে PersonDTO তে ম্যাপিং পরীক্ষা করা হচ্ছে।
সারাংশ
MapStruct এবং Spring ফ্রেমওয়ার্কের মধ্যে ইন্টিগ্রেশন অত্যন্ত কার্যকরী। MapStruct এর মাধ্যমে Spring Beans এবং Dependency Injection ব্যবহারের মাধ্যমে ম্যাপিং প্রক্রিয়া সহজ এবং দ্রুত করা যায়। MapStruct এর সাথে Spring DI ব্যবহার করলে ডোমেইন অবজেক্ট থেকে DTO-তে ম্যাপিং করা সহজ হয়, এবং এতে পারফরম্যান্সে কোন প্রভাব পড়ে না। Spring কনটেক্সটের মধ্যে মেভেন ও গ্র্যাডল সাপোর্টেড MapStruct এর মাধ্যমে অ্যাপ্লিকেশন টেস্টিং এবং প্রোজেক্ট ডেভেলপমেন্ট আরও সহজ হয়ে ওঠে।
MapStruct একটি Java annotation processor ভিত্তিক টুল যা JavaBeans (POJOs) এর মধ্যে ডেটা ম্যাপিং করে থাকে। @Mapper(componentModel = "spring") অ্যানোটেশনটি MapStruct ইন্টারফেসের মধ্যে ব্যবহার করা হয় এবং এটি MapStruct কে Spring ফ্রেমওয়ার্কের সাথে ইন্টিগ্রেট করার জন্য ব্যবহৃত হয়। এই কনফিগারেশনের মাধ্যমে MapStruct স্বয়ংক্রিয়ভাবে Spring Bean হিসেবে ম্যাপিং ক্লাসটিকে রেজিস্টার করে, যাতে সহজেই Spring context এ ইনজেক্ট করা যায়।
এটি বিশেষভাবে Spring Boot অ্যাপ্লিকেশনগুলিতে MapStruct ব্যবহার করার জন্য কার্যকরী, কারণ Spring Framework আপনাকে dependency injection এর মাধ্যমে মাপিং অবজেক্ট স্বয়ংক্রিয়ভাবে ইনজেক্ট করতে সহায়তা করে।
১. @Mapper(componentModel = "spring") এর ভূমিকা
componentModel = "spring"সেট করা হলে, MapStruct Spring Bean হিসেবে কাজ করবে।- এটি @Autowired সহ Spring context এ ম্যাপিং ক্লাসের ইনস্ট্যান্সকে স্বয়ংক্রিয়ভাবে ইনজেক্ট করতে সহায়তা করে।
- এর মাধ্যমে MapStruct এর মাধ্যমে তৈরি করা Mapper ইন্টারফেসটি Spring Beans হিসেবে রেজিস্টার হয় এবং Spring এর dependency injection প্রক্রিয়ার মধ্যে ব্যবহার করা যায়।
২. @Mapper(componentModel = "spring") কনফিগারেশন উদাহরণ
ধরা যাক, আমরা একটি Spring Boot অ্যাপ্লিকেশনে MapStruct ব্যবহার করছি এবং আমাদের একটি Person অবজেক্টকে PersonDTO তে ম্যাপ করতে হবে।
Step 1: Maven ডিপেনডেন্সি যোগ করা
pom.xml ফাইলে MapStruct এর ডিপেনডেন্সি যোগ করুন।
<dependencies>
<!-- MapStruct Dependency -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<!-- MapStruct Processor for compile-time code generation -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- Spring Boot Dependency (if needed) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
Step 2: MapStruct Mapper ইন্টারফেস তৈরি করা
এখন, MapStruct মেপার ইন্টারফেস তৈরি করুন এবং @Mapper(componentModel = "spring") অ্যানোটেশন যোগ করুন।
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import org.springframework.stereotype.Component;
@Mapper(componentModel = "spring") // This makes the Mapper a Spring Bean
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
PersonDTO personToPersonDTO(Person person);
}
এখানে, @Mapper(componentModel = "spring") ব্যবহার করা হয়েছে, যাতে PersonMapper ইন্টারফেসটি Spring Bean হিসেবে রেজিস্টার হয়।
Step 3: DTO ক্লাস তৈরি করা
এখন, Person এবং PersonDTO ক্লাস তৈরি করুন।
Person.java:
public class Person {
private String name;
private int age;
// Getters and Setters
}
PersonDTO.java:
public class PersonDTO {
private String name;
private int age;
// Getters and Setters
}
Step 4: Spring Service এ Mapper ইনজেক্ট করা
এখন, Spring Service ক্লাসে PersonMapper ইনজেক্ট করুন।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService {
private final PersonMapper personMapper;
@Autowired
public PersonService(PersonMapper personMapper) {
this.personMapper = personMapper;
}
public PersonDTO convertToDTO(Person person) {
return personMapper.personToPersonDTO(person);
}
}
এখানে, PersonMapper কে @Autowired এর মাধ্যমে Spring context থেকে ইনজেক্ট করা হয়েছে।
Step 5: Spring Boot Application
এখন, Spring Boot অ্যাপ্লিকেশনে এটি ব্যবহার করা যেতে পারে।
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private PersonService personService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
Person person = new Person();
person.setName("John Doe");
person.setAge(30);
PersonDTO personDTO = personService.convertToDTO(person);
System.out.println("Person DTO Name: " + personDTO.getName());
System.out.println("Person DTO Age: " + personDTO.getAge());
}
}
এখানে, CommandLineRunner ইন্টারফেস ব্যবহার করে আমরা Person অবজেক্টকে PersonDTO তে কনভার্ট করেছি এবং প্রিন্ট করেছি।
৩. @Mapper(componentModel = "spring") এর সুবিধা
- Spring Integration: এটি Spring ফ্রেমওয়ার্কের সাথে সহজভাবে ইন্টিগ্রেট করতে সাহায্য করে এবং dependency injection এর মাধ্যমে MapStruct এর মাপিং অবজেক্ট স্বয়ংক্রিয়ভাবে ইনজেক্ট করা যায়।
- Cleaner Code: Mapper ক্লাসে
@Mapper(componentModel = "spring")যোগ করলে Spring এর মধ্যে MapStruct ইন্টারফেস স্বয়ংক্রিয়ভাবে রেজিস্টার হয়ে যায়, যা কোডের পরিস্কারতা এবং কার্যকারিতা বৃদ্ধি করে। - Easier Testing: MapStruct এর Spring Bean হিসেবে ব্যবহৃত হওয়ার ফলে, আপনি সহজেই এটি Unit Test করতে পারেন।
- No Boilerplate Code: MapStruct এর মাধ্যমে স্বয়ংক্রিয়ভাবে কোড জেনারেট করা হয়, ফলে আপনাকে ম্যানুয়ালি কোন ম্যাপিং কোড লেখার প্রয়োজন হয় না।
৪. নির্ধারিত পরিবেশে @Mapper(componentModel = "spring") এর ব্যবহার
- Spring Boot: Spring Boot অ্যাপ্লিকেশনগুলিতে MapStruct দ্রুত এবং সহজে ইন্টিগ্রেট করা যায়।
- Spring Framework: Spring Framework ব্যবহারের সময় MapStruct খুব সহজে Spring Beans হিসাবে ব্যবহৃত হতে পারে।
সারাংশ
@Mapper(componentModel = "spring") এর মাধ্যমে MapStruct মেপার ইন্টারফেসকে Spring Bean হিসেবে রেজিস্টার করা হয়। এটি Spring ফ্রেমওয়ার্কে ব্যবহার করা হলে, আপনি dependency injection এর মাধ্যমে MapStruct মেপিং অবজেক্ট স্বয়ংক্রিয়ভাবে ইনজেক্ট করতে পারেন, যা কোড ক্লিন এবং কার্যকরী করে তোলে। MapStruct এর মাধ্যমে Spring অ্যাপ্লিকেশনগুলিতে ম্যাপিং কোড খুব সহজেই তৈরি করা যায়, যা উন্নত পারফরম্যান্স এবং উন্নত এক্সপ্যান্সিবিলিটি প্রদান করে।
MapStruct একটি annotation-based code generator যা JavaBeans এর মধ্যে ম্যাপিং অপারেশন সহজ এবং পারফর্ম্যান্টভাবে সম্পাদন করতে ব্যবহৃত হয়। এটি Spring ফ্রেমওয়ার্কের সাথে খুব সহজে ইন্টিগ্রেট করা যায় এবং MapStruct এর মেথডগুলি Spring Beans হিসেবে ব্যবহার করা সম্ভব হয়।
এই টিউটোরিয়ালে আমরা দেখবো MapStruct এর মাধ্যমে Spring Integration কিভাবে করা যায় এবং Spring Beans হিসেবে মেপিং কনফিগারেশন কিভাবে তৈরি করতে হয়।
১. Spring Integration with MapStruct
MapStruct এর সাথে Spring ইন্টিগ্রেট করার জন্য আপনাকে কিছু কনফিগারেশন করতে হবে, যাতে MapStruct এর তৈরি করা Mapper Interface কে Spring Beans হিসেবে ব্যবহৃত করা যায়। Spring এ এটি করার জন্য, @Mapper(componentModel = "spring") অ্যানোটেশন ব্যবহার করা হয়।
এটি Spring Container এ Mapper ইনস্ট্যান্স তৈরি করতে সহায়তা করে, যার ফলে আপনি Spring এর মাধ্যমে মেপিং সেবা ব্যবহার করতে পারবেন।
উদাহরণ: Spring Integration with MapStruct
ধরা যাক, আমাদের দুটি JavaBean Person এবং PersonDTO রয়েছে, এবং আমরা এগুলির মধ্যে ম্যাপিং করতে চাই। Spring Integration এর মাধ্যমে আমরা MapStruct Mapper এর সাহায্যে এই ম্যাপিং প্রক্রিয়া সম্পন্ন করবো।
২. Spring এর সাথে MapStruct সেটআপ
প্রথমে, আমাদের MapStruct এর প্রয়োজনীয় ডিপেনডেন্সি pom.xml ফাইলে যুক্ত করতে হবে।
Maven ডিপেনডেন্সি:
<dependencies>
<!-- MapStruct Dependency -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<!-- MapStruct Processor (for compile-time code generation) -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- Spring Boot Dependency (for integration) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
এখানে, MapStruct এবং MapStruct Processor এর ডিপেনডেন্সি গুলি যুক্ত করা হয়েছে, যা compile-time কোড জেনারেট করতে সাহায্য করবে।
৩. MapStruct Mapper Interface এর কনফিগারেশন
Spring Integration এর জন্য, @Mapper অ্যানোটেশন ব্যবহার করা হয়, এবং componentModel = "spring" প্রপার্টি দিয়ে এটি Spring Bean হিসেবে কনফিগার করা হয়।
উদাহরণ: Mapper Interface
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public interface PersonMapper {
// Mapping method to map Person to PersonDTO
PersonDTO personToPersonDTO(Person person);
}
এখানে, componentModel = "spring" ব্যবহৃত হয়েছে, যা MapStruct কে Spring Beans হিসেবে কাজ করার অনুমতি দেয়। এর ফলে PersonMapper কে Spring Context এর মধ্যে ইন্টিগ্রেট করা যাবে।
৪. Person এবং PersonDTO ক্লাস
এখন, Person এবং PersonDTO ক্লাস তৈরি করি, যেগুলির মধ্যে ম্যাপিং করা হবে।
Person.java (Domain Object):
public class Person {
private String name;
private int age;
// Getters and Setters
}
PersonDTO.java (DTO):
public class PersonDTO {
private String name;
private int age;
// Getters and Setters
}
৫. Spring Service বা Controller এ MapStruct Mapper ব্যবহার
এখন, আপনি Spring Service বা Controller ক্লাসে PersonMapper কে Autowired দিয়ে ব্যবহার করতে পারেন।
PersonService.java (Spring Service):
import org.springframework.stereotype.Service;
@Service
public class PersonService {
private final PersonMapper personMapper;
// Injecting the Mapper
public PersonService(PersonMapper personMapper) {
this.personMapper = personMapper;
}
public PersonDTO convertPersonToDTO(Person person) {
return personMapper.personToPersonDTO(person);
}
}
এখানে, PersonMapper কে Spring Bean হিসেবে ইনজেক্ট করা হয়েছে এবং convertPersonToDTO মেথডে Person অবজেক্টকে PersonDTO তে ম্যাপ করা হচ্ছে।
৬. Spring Controller এ MapStruct Mapper ব্যবহার
Spring Controller এর মধ্যে PersonService ব্যবহার করে আপনি API রাউটেও MapStruct ম্যাপিং ব্যবহার করতে পারেন।
PersonController.java (Spring Controller):
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PersonController {
private final PersonService personService;
public PersonController(PersonService personService) {
this.personService = personService;
}
@GetMapping("/convert")
public PersonDTO convertPersonToDTO() {
Person person = new Person();
person.setName("John Doe");
person.setAge(30);
return personService.convertPersonToDTO(person);
}
}
এখানে, PersonController এ PersonService ইনজেক্ট করা হয়েছে এবং একটি GET API তৈরি করা হয়েছে যা Person অবজেক্টকে PersonDTO তে কনভার্ট করে।
৭. Spring Boot অ্যাপ্লিকেশন চালানো
এখন, আপনার Spring Boot অ্যাপ্লিকেশন চলবে এবং MapStruct এর মাধ্যমে Person থেকে PersonDTO ম্যাপিং হয়ে যাবে। অ্যাপ্লিকেশন চালানোর পর, আপনি http://localhost:8080/convert URL এ GET রিকোয়েস্ট করলে PersonDTO আউটপুট পাবেন।
সারাংশ
MapStruct এবং Spring Integration একসাথে ব্যবহারের মাধ্যমে আপনি সহজেই আপনার JavaBeans বা DTOs এর মধ্যে দ্রুত এবং কার্যকরী ম্যাপিং করতে পারেন। MapStruct এর componentModel = "spring" কনফিগারেশন Spring Beans হিসেবে Mapper এর ইন্টিগ্রেশন সহজ করে দেয়। এর ফলে, আপনি আপনার Service বা Controller ক্লাসে MapStruct Mapper ব্যবহার করতে পারেন, যা আপনার কোডকে পরিষ্কার এবং সহজ করে তোলে।
MapStruct এর সাথে Spring ইন্টিগ্রেট করা খুবই সহজ এবং এটি Spring প্রোজেক্টগুলিতে ম্যাপিংয়ের জন্য একটি শক্তিশালী এবং কার্যকরী সমাধান প্রদান করে।
Read more