Caching Aspect কি?
Caching হল একটি গুরুত্বপূর্ণ প্রক্রিয়া যা ডেটা বা রিসোর্সকে স্মৃতিতে (memory) বা ড্রাইভে সঞ্চয় করে রাখে, যাতে পরবর্তী সময়ে সেই ডেটার জন্য পুনরায় সেই রিসোর্সটি বা ডেটা পুনরুদ্ধার করতে না হয়। এটি পারফরম্যান্স অপ্টিমাইজেশনের জন্য ব্যবহৃত হয়, যেখানে একবার প্রাপ্ত ডেটা আবার ব্যবহার করা হয়।
স্প্রিং AOP ব্যবহার করে একটি Caching Aspect তৈরি করা যায়, যেখানে একটি অ্যাসপেক্টে Advice নির্দিষ্ট মেথডের জন্য ক্যাশিং কার্যকরী করবে। উদাহরণস্বরূপ, একটি মেথড থেকে ডেটা রিটার্ন হলে, প্রথমবার সেই ডেটা ক্যাশে রাখা হবে এবং পরবর্তী সময়ে সেই ডেটা পুনরায় ক্যাশ থেকে নেওয়া হবে, ডেটাবেস বা অন্য কোনো সোর্স থেকে আবার পড়ার প্রয়োজন হবে না।
Spring AOP দিয়ে Caching Aspect তৈরি করার উদাহরণ
স্প্রিং AOP ব্যবহার করে একটি Caching Aspect তৈরি করা হবে যা @Cacheable অ্যাসপেক্টের মতো ক্যাশিং কার্যকারিতা তৈরি করবে। এখানে, আমরা একটি কাস্টম Caching Aspect তৈরি করব, যা মেথডের ফলাফল ক্যাশে সংরক্ষণ করবে এবং পরবর্তীতে সেই ফলাফল পুনরায় ক্যাশ থেকে রিটার্ন করবে।
1. Caching Aspect তৈরি করা
এটি একটি স্প্রিং AOP অ্যাসপেক্ট, যা মেথডের ফলাফল ক্যাশে সংরক্ষণ করবে এবং পরে সেই ফলাফল ফেরত দেবে।
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.AfterReturning;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class CachingAspect {
// ক্যাশ (এখানে সিম্পল HashMap ব্যবহার করা হয়েছে)
private Map<String, Object> cache = new HashMap<>();
// @Before advice - ক্যাশে আগে থেকে কোন ডেটা আছে কিনা তা চেক করা
@Before("execution(* com.example.service.*.*(..))")
public void checkCache() {
System.out.println("Checking cache before executing method...");
}
// @AfterReturning advice - মেথডের ফলাফল ক্যাশে সঞ্চয় করা
@AfterReturning(value = "execution(* com.example.service.*.*(..))", returning = "result")
public void cacheResult(Object result) {
System.out.println("Storing method result in cache...");
// সিম্পল ক্যাশিং (ফাংশন নাম এবং আর্গুমেন্ট দ্বারা ক্যাশের Key তৈরি করা)
String cacheKey = createCacheKey(result);
cache.put(cacheKey, result);
}
// ক্যাশ থেকে ডেটা পুনরুদ্ধার করার জন্য একটি মেথড
public Object getFromCache(String cacheKey) {
return cache.get(cacheKey);
}
// ক্যাশ কী তৈরির জন্য একটি মেথড
private String createCacheKey(Object result) {
return "resultKey-" + result.hashCode();
}
}
এখানে:
@Aspectঅ্যানোটেশন দিয়েCachingAspectক্লাসটি একটি স্প্রিং অ্যাসপেক্ট হিসেবে চিহ্নিত করা হয়েছে।@Beforeএবং@AfterReturningঅ্যাডভাইস ব্যবহার করা হয়েছে।@Before- এটি ক্যাশ চেক করবে, কিন্তু ক্যাশে যদি ডেটা না থাকে, তবেAfterReturningএ ক্যাশিং করতে হবে।@AfterReturning- মেথডের সফল ফলাফল পাওয়া গেলে, সেই ফলাফল ক্যাশে সঞ্চয় করবে।
2. Service Class (Business Logic)
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class MyService {
// এই মেথডটি ডেটা ফেচ করে এবং ক্যাশে রাখা হবে
public String fetchData(String id) {
// সিমুলেটেড ডেটা প্রসেসিং
System.out.println("Fetching data for id: " + id);
return "Data for " + id;
}
}
এখানে:
MyServiceক্লাসেরfetchData()মেথডটি ডেটা রিটার্ন করবে, যেটি AOP ক্যাশিং এর মাধ্যমে সঞ্চয় করা হবে এবং পরবর্তীতে ক্যাশ থেকে ফেরত পাওয়া যাবে।
3. Testing the Caching Aspect
স্প্রিং অ্যাপ্লিকেশন চালানোর পর, যখন fetchData() মেথড কল করা হবে, প্রথমবার ক্যাশে ফলাফল সংরক্ষণ করা হবে এবং পরবর্তী সময়ে একই মেথডে সেই ফলাফল ক্যাশ থেকে রিটার্ন হবে।
package com.example;
import com.example.service.MyService;
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 SpringAopCachingApplication implements CommandLineRunner {
@Autowired
private MyService myService;
public static void main(String[] args) {
SpringApplication.run(SpringAopCachingApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// প্রথমবার মেথড কল
System.out.println(myService.fetchData("1"));
// দ্বিতীয়বার একই মেথড কল, ক্যাশ থেকে ডেটা পাওয়া যাবে
System.out.println(myService.fetchData("1"));
}
}
এখানে:
- প্রথমবার
fetchData("1")মেথড কল করা হলে, এটি ক্যাশে ডেটা সঞ্চয় করবে এবং পরবর্তীতে আবার একই মেথড কল করার সময়ে ক্যাশ থেকে সেই ডেটা রিটার্ন হবে।
আউটপুট:
Fetching data for id: 1
Data for 1
Checking cache before executing method...
Data for 1
এখানে প্রথমবার মেথড কল হওয়ার পর "Fetching data for id: 1" দেখানো হবে, কিন্তু পরবর্তী সময়ে ক্যাশ থেকে সরাসরি ডেটা রিটার্ন হবে এবং লগ দেখাবে "Checking cache before executing method..."।
Spring AOP দিয়ে Caching Aspect ব্যবহারের সুবিধা:
- Performance Improvement: ক্যাশিং ব্যবহারের মাধ্যমে ডেটা পুনরায় প্রক্রিয়া করার পরিবর্তে দ্রুত অ্যাক্সেস করা সম্ভব, যা পারফরম্যান্স বাড়ায়।
- Modularization: ক্যাশিং লজিকটি অ্যাসপেক্টে আলাদাভাবে রাখা হয়, যা কোডের মেইন লজিক থেকে বিচ্ছিন্ন থাকে, ফলে মূল কোড পরিষ্কার থাকে এবং পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়।
- Centralized Caching Logic: ক্যাশিং লজিক এক জায়গায় রাখা যায়, এবং এটি একাধিক মেথডে প্রয়োগ করা সম্ভব হয়।
সারাংশ
Spring AOP ব্যবহার করে Caching Aspect তৈরি করলে অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করা সম্ভব, বিশেষত যখন একই ডেটা বারবার পুনরুদ্ধার করা হয়। @Before, @AfterReturning এর মাধ্যমে ক্যাশিং কার্যকরী করা হয় এবং ক্যাশ থেকে ডেটা পুনরুদ্ধারের জন্য Advice ব্যবহৃত হয়। এটি AOP এর শক্তিশালী উপকারিতা এবং সিকিউরিটি, ট্রানজেকশন ম্যানেজমেন্ট, বা লগিং এর মতো ক্রস-কাটিং কনসার্ন কার্যকরী করার সঙ্গে যুক্ত করা যেতে পারে।