Pointcut Expressions স্প্রিং AOP (Aspect-Oriented Programming) এর একটি গুরুত্বপূর্ণ অংশ যা নির্ধারণ করে যে কোন মেথড বা ক্লাসের উপর অ্যাডভাইস (Advice) প্রয়োগ হবে। এটি Join Points চিহ্নিত করতে সাহায্য করে, অর্থাৎ যেখানে আপনার অ্যাসপেক্টের কাস্টম লজিক প্রয়োগ করা হবে। স্প্রিং AOP তে Pointcut হল এমন একটি অভিব্যক্তি (expression) যা টার্গেট মেথডগুলিকে নির্বাচন করতে ব্যবহৃত হয়, এবং Advice সেই নির্বাচিত মেথডগুলির উপর কার্যকর হয়।
Pointcut Expressions এর ধরন
স্প্রিং AOP তে Pointcut Expressions বেশ কিছু ভিন্ন ধরনে ব্যবহৃত হয়, যেমন:
- execution(): মেথড এক্সিকিউশনের উপর ভিত্তি করে
- within(): নির্দিষ্ট প্যাকেজ বা ক্লাসের মধ্যে
- args(): মেথডের প্যারামিটার টাইপের উপর ভিত্তি করে
- @annotation(): নির্দিষ্ট অ্যানোটেশন সহ মেথডের উপর ভিত্তি করে
Pointcut Expressions এর সাধারণ গঠন
@Pointcut("execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(parameter-pattern) throws-pattern?)")
public void pointcutExpression() {}
এখানে:
execution()হল সবচেয়ে সাধারণ এবং গুরুত্বপূর্ণ পয়েন্টকাট এক্সপ্রেশন, যা মেথডের সিগনেচার নির্ধারণ করে।modifiers-pattern?(ঐচ্ছিক) মেথডের মডিফায়ার যেমনpublic,privateইত্যাদি।return-type-pattern?মেথডের রিটার্ন টাইপ (যেমনvoid,Stringইত্যাদি)।declaring-type-pattern?মেথডটি যে ক্লাসে বা ইন্টারফেসে অবস্থিত।method-name-patternমেথডের নাম।parameter-patternমেথডের প্যারামিটার টাইপ।throws-pattern?মেথডের থ্রো করা এক্সেপশন।
উদাহরণ সহ Pointcut Expressions ব্যবহার
Step 1: Service Class (Target Methods)
প্রথমে একটি EmployeeService ক্লাস তৈরি করি যার মধ্যে কিছু মেথড রয়েছে।
public class EmployeeService {
public void addEmployee(String name) {
System.out.println(name + " added successfully!");
}
public void deleteEmployee(String name) {
System.out.println(name + " deleted successfully!");
}
public String getEmployeeInfo(int id) {
return "Employee info for id: " + id;
}
}
এখানে, আমাদের EmployeeService ক্লাসে তিনটি মেথড রয়েছে: addEmployee(), deleteEmployee(), এবং getEmployeeInfo()।
Step 2: Aspect Class with Pointcut Expressions
এখন, আমরা একটি Aspect ক্লাস তৈরি করব, যেখানে বিভিন্ন ধরনের Pointcut Expressions ব্যবহার করে Advice প্রয়োগ করা হবে।
@Aspect
@Component
public class LoggingAspect {
// Pointcut expression for all methods in EmployeeService
@Pointcut("execution(* EmployeeService.*(..))")
public void allMethodsInEmployeeService() {}
// Before advice using the above pointcut
@Before("allMethodsInEmployeeService()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method execution: " + joinPoint.getSignature().getName());
}
// Pointcut expression for methods with specific parameter types (String)
@Pointcut("execution(* EmployeeService.addEmployee(String))")
public void addEmployeeMethodWithStringParam() {}
// After advice for methods that match the above pointcut
@After("addEmployeeMethodWithStringParam()")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method execution: " + joinPoint.getSignature().getName());
}
// Pointcut expression for methods with a return type of String
@Pointcut("execution(String EmployeeService.getEmployeeInfo(..))")
public void getEmployeeInfoMethod() {}
// Around advice for the method matching the above pointcut
@Around("getEmployeeInfoMethod()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before around advice: " + joinPoint.getSignature().getName());
Object result = joinPoint.proceed();
System.out.println("After around advice: " + joinPoint.getSignature().getName());
return result;
}
}
Explanation:
@Pointcut("execution(* EmployeeService.*(..))"): এই পয়েন্টকাট এক্সপ্রেশনটিEmployeeServiceক্লাসের সব মেথডের উপর প্রয়োগ হবে।execution()দ্বারা মেথডের সিগনেচার নির্বাচন করা হয়, যেখানে*অর্থ যে কোন রিটার্ন টাইপ, এবং(..)অর্থ যে কোনো প্যারামিটার।@Before("allMethodsInEmployeeService()"): এই অ্যাডভাইসটিallMethodsInEmployeeService()পয়েন্টকাটের জন্য আগে কার্যকর হবে। অর্থাৎ, যখনইEmployeeServiceএর কোনো মেথড কল হবে, তখন এটি তার আগে কার্যকর হবে।@Pointcut("execution(* EmployeeService.addEmployee(String))"): এখানেaddEmployee()মেথডের জন্য পয়েন্টকাট এক্সপ্রেশন তৈরি করা হয়েছে, যা শুধুStringপ্যারামিটার গ্রহণকারীaddEmployeeমেথডের উপর কাজ করবে।@After("addEmployeeMethodWithStringParam()"): এই অ্যাডভাইসটিaddEmployee()মেথডের পরে কার্যকর হবে। এটিaddEmployeeমেথডের কলের পরে লগিং করবে।@Pointcut("execution(String EmployeeService.getEmployeeInfo(..))"): এই পয়েন্টকাট এক্সপ্রেশনটিgetEmployeeInfo()মেথডের জন্য তৈরি করা হয়েছে, যাStringরিটার্ন টাইপ সহ।@Around("getEmployeeInfoMethod()"): এটি একটি Around Advice, যাgetEmployeeInfo()মেথডের আগে এবং পরে কার্যকর হবে। এটি মেথডের এক্সিকিউশনের আগেই কিছু লজিক এবং পরে কিছু লজিক প্রয়োগ করতে সাহায্য করে।
Step 3: Configuration Class
স্প্রিং কনটেক্সটের জন্য এএফপি (AOP) সক্রিয় করতে আপনাকে @EnableAspectJAutoProxy অ্যানোটেশন ব্যবহার করতে হবে।
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.example") // আপনার প্যাকেজ স্ক্যান করুন
public class AppConfig {
}
Step 4: Main Application
এখন, আমাদের স্প্রিং অ্যাপ্লিকেশন তৈরি করে মেথডগুলো কল করব।
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
EmployeeService employeeService = context.getBean(EmployeeService.class);
// মেথড কল করব যাতে Pointcut Expressions কার্যকর হয়
employeeService.addEmployee("John");
employeeService.deleteEmployee("Alice");
System.out.println(employeeService.getEmployeeInfo(101));
context.close();
}
}
Output:
Before method execution: addEmployee
After method execution: addEmployee
Before around advice: getEmployeeInfo
After around advice: getEmployeeInfo
এখানে, Before এবং After অ্যাডভাইস যথাক্রমে মেথড কলের আগে এবং পরে কার্যকর হয়েছে, এবং Around অ্যাডভাইস getEmployeeInfo মেথডের আগে এবং পরে কার্যকর হয়েছে।
Conclusion
স্প্রিং AOP তে Pointcut Expressions ব্যবহার করে আপনি নির্দিষ্ট মেথড বা ক্লাসের উপর অ্যাডভাইস প্রয়োগ করতে পারেন। execution(), within(), args(), @annotation() ইত্যাদি পয়েন্টকাট এক্সপ্রেশন স্প্রিং এওপিতে খুবই শক্তিশালী এবং উপকারী। এটি ক্রস-কাটিং কনসার্ন (যেমন লগিং, সিকিউরিটি) আলাদাভাবে এবং আরো কার্যকরভাবে পরিচালনা করতে সাহায্য করে।