জাভার java.lang.reflect.Proxy
এবং ডাইনামিক প্রক্সি ক্লাস হলো শক্তিশালী টুলস যা আপনাকে রানটাইমে অবজেক্ট তৈরি করার সুবিধা প্রদান করে, যেখানে আপনি একটি ইন্টারফেসের মাধ্যমে বিভিন্ন ক্লাসের মেথড ইমপ্লিমেন্ট করতে পারেন। এটি মূলত ডাইনামিক প্রক্সি প্যাটার্ন (Dynamic Proxy Pattern) এর উপর ভিত্তি করে কাজ করে এবং ব্যবহারকারীদের সিস্টেমের আচরণ পরিবর্তন করতে সক্ষম করে।
Proxy
ক্লাসটি একটি ডাইনামিক প্রক্সি ক্লাস তৈরি করতে ব্যবহৃত হয়। এটি java.lang.reflect.InvocationHandler
ইন্টারফেসের সাহায্যে মেথড কল করার সুযোগ দেয়।
ডাইনামিক প্রক্সি এমন একটি অবজেক্ট যা কোনও ক্লাসের মেথডগুলি রানটাইমে হ্যান্ডেল করে। এটি সাধারণত একটি বা একাধিক ইন্টারফেস ইমপ্লিমেন্ট করে, এবং কোনও ইন্টারফেসের মেথড কল করা হলে InvocationHandler
এর invoke()
মেথডটিতে পৌঁছায়, যেখানে আপনি সেই মেথডের আচরণ কাস্টমাইজ করতে পারেন।
ডাইনামিক প্রক্সি তৈরি করার জন্য তিনটি প্রধান উপাদান রয়েছে:
ধরা যাক, আমাদের একটি ইন্টারফেস এবং তার কনক্রিট ক্লাস রয়েছে:
public interface Hello {
void sayHello();
void sayGoodbye();
}
public class HelloImpl implements Hello {
@Override
public void sayHello() {
System.out.println("Hello!");
}
@Override
public void sayGoodbye() {
System.out.println("Goodbye!");
}
}
InvocationHandler
ইন্টারফেসে invoke()
মেথডটি ব্যবহার করে আমরা কাস্টম মেথড কল হ্যান্ডলিং করতে পারি।
import java.lang.reflect.*;
public class HelloInvocationHandler implements InvocationHandler {
private Object target;
public HelloInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
এখানে, invoke()
মেথডটি যখন মেথড কল হবে তখন তার আগে এবং পরে কাস্টম কোড কার্যকর হবে।
import java.lang.reflect.*;
public class ProxyExample {
public static void main(String[] args) {
// বাস্তব ক্লাসের অবজেক্ট তৈরি
Hello realHello = new HelloImpl();
// InvocationHandler এর সাহায্যে প্রক্সি অবজেক্ট তৈরি
Hello proxyHello = (Hello) Proxy.newProxyInstance(
realHello.getClass().getClassLoader(),
realHello.getClass().getInterfaces(),
new HelloInvocationHandler(realHello)
);
// প্রক্সি অবজেক্টের মেথড কল করা
proxyHello.sayHello();
proxyHello.sayGoodbye();
}
}
Hello
ইন্টারফেসে দুটি মেথড sayHello()
এবং sayGoodbye()
রয়েছে।Hello
ইন্টারফেসের একটি কনক্রিট ইমপ্লিমেন্টেশন, যা আসলে মেথডগুলো বাস্তবায়ন করে।InvocationHandler
ইন্টারফেসের ইমপ্লিমেন্টেশন, যা মেথড কল হ্যান্ডল করার জন্য ব্যবহৃত হয়।realHello
অবজেক্টের মেথডগুলি ইন্টারসেপ্ট করে এবং invoke()
মেথডের মাধ্যমে হ্যান্ডল করা হয়।Before method: sayHello
Hello!
After method: sayHello
Before method: sayGoodbye
Goodbye!
After method: sayGoodbye
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
:InvocationHandler
অবজেক্ট, যা প্রক্সি অবজেক্টের মেথড কল হ্যান্ডল করবে।Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces)
:Proxy.isProxyClass(Class<?> cl)
:জাভা রিফ্লেকশন প্যাকেজের Proxy ক্লাস এবং ডাইনামিক প্রক্সি প্যাটার্ন ডাইনামিকভাবে ইন্টারফেসের মেথডগুলোকে কাস্টমাইজ করার জন্য খুবই শক্তিশালী একটি টুল। এটি বিশেষ করে লগিং, ট্রানজেকশন, ডিবাগিং, এবং প্রোগ্রাম্যাটিক্যালি মেথড ইমপ্লিমেন্টেশনের জন্য ব্যবহার করা হয়।
Java রিফ্লেকশন প্যাকেজে Proxy
ক্লাস একটি গুরুত্বপূর্ণ কনসেপ্ট। এটি ডাইনামিক প্রক্সি অবজেক্ট তৈরি করতে ব্যবহৃত হয়, যার মাধ্যমে আপনি রানটাইমে একটি বা একাধিক ইন্টারফেস বাস্তবায়ন (implement) করা অবজেক্ট তৈরি করতে পারেন। Proxy Class সাধারণত ব্যবহার হয় এমন পরিস্থিতিতে যেখানে আপনাকে ইন্টারফেসের মাধ্যমে বিভিন্ন কাস্টম আচরণ (custom behavior) যুক্ত করতে হয়, বিশেষ করে যখন মেথড কলের উপর কিছু অতিরিক্ত কার্যকারিতা যোগ করতে চান।
Proxy
একটি বিশেষ ক্লাস যা Java ইন্টারফেসগুলিকে ডাইনামিকভাবে ইমপ্লিমেন্ট করে, এবং InvocationHandler
ইন্টারফেস ব্যবহার করে মেথড কলের জন্য কাস্টম কার্যকারিতা (custom behavior) নির্ধারণ করতে সাহায্য করে। এটি মূলত ডাইনামিক প্রক্সি অবজেক্ট তৈরি করতে ব্যবহৃত হয় যা রানটাইমে ইন্টারফেসের মেথডগুলোকে ইমপ্লিমেন্ট করে।
Proxy
ক্লাসের প্রধান মেথডগুলো:newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
:InvocationHandler
দ্বারা কাস্টম মেথড কলের আচরণ নির্ধারণ করে।loader
: ক্লাসলোডার, যা প্রক্সি ক্লাস লোড করে।interfaces
: ইন্টারফেসের অ্যারে, যেগুলি প্রক্সি ক্লাস ইমপ্লিমেন্ট করবে।handler
: InvocationHandler
অবজেক্ট, যা মেথড কলের আচরণ নির্ধারণ করে।InvocationHandler
ইন্টারফেস:invoke()
মেথড প্রদান করে।Proxy
ক্লাস খুবই কার্যকরী। আপনি মেথড কল হ্যান্ডলিংয়ের জন্য কাস্টম আচরণ নির্ধারণ করতে পারেন।Proxy
ক্লাস ব্যবহার করে, আপনি একাধিক ইন্টারফেসের মেথড কল করতে পারেন এবং আপনার কাস্টম আচরণ প্রয়োগ করতে পারেন, যা সাধারণভাবে সম্ভব নয়।Proxy
ক্লাস ডাইনামিকভাবে প্রক্সি অবজেক্ট তৈরি করে এবং নির্দিষ্ট মেথড কাস্টমাইজ করতে পারে।ধরা যাক, আপনি একটি ইন্টারফেস MyInterface
তৈরি করেছেন এবং এটি প্রক্সি ক্লাসের মাধ্যমে ইমপ্লিমেন্ট করতে চান।
import java.lang.reflect.*;
interface MyInterface {
void sayHello();
void sayGoodbye();
}
class MyInvocationHandler implements InvocationHandler {
private final Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// কাস্টম লোগিক যোগ করা
System.out.println("Before method call: " + method.getName());
Object result = method.invoke(target, args); // মূল মেথড কল
System.out.println("After method call: " + method.getName());
return result;
}
}
class MyImplementation implements MyInterface {
@Override
public void sayHello() {
System.out.println("Hello!");
}
@Override
public void sayGoodbye() {
System.out.println("Goodbye!");
}
}
public class ProxyExample {
public static void main(String[] args) {
// মূল অবজেক্ট তৈরি
MyInterface realObject = new MyImplementation();
// InvocationHandler তৈরি
MyInvocationHandler handler = new MyInvocationHandler(realObject);
// প্রক্সি অবজেক্ট তৈরি
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class<?>[] { MyInterface.class },
handler
);
// প্রক্সি মেথড কল
proxy.sayHello(); // "Before method call" -> "Hello!" -> "After method call"
proxy.sayGoodbye(); // "Before method call" -> "Goodbye!" -> "After method call"
}
}
MyInterface
:sayHello()
এবং sayGoodbye()
ডিফাইন করেছে।MyInvocationHandler
:InvocationHandler
ইন্টারফেসের একটি কাস্টম বাস্তবায়ন, যা invoke()
মেথডে কাস্টম আচরণ যোগ করতে ব্যবহার করা হয়েছে। এখানে, প্রাথমিকভাবে মেথড কলের আগে এবং পরে কিছু লোগিং প্রিন্ট করা হচ্ছে।Proxy.newProxyInstance()
:newProxyInstance()
মেথডের মাধ্যমে একটি নতুন প্রক্সি অবজেক্ট তৈরি করা হচ্ছে যা MyInterface
ইন্টারফেস ইমপ্লিমেন্ট করে। InvocationHandler
প্রদান করে, যা মেথড কল হ্যান্ডল করে।proxy.sayHello()
এবং proxy.sayGoodbye()
:sayHello()
এবং sayGoodbye()
মেথডগুলি প্রক্সি অবজেক্টের মাধ্যমে কল করা হচ্ছে, এবং এসময় প্রক্সি অবজেক্টের মধ্যে কাস্টম আচরণ (মেথডের আগে এবং পরে লোগিং) যোগ করা হচ্ছে।Before method call: sayHello
Hello!
After method call: sayHello
Before method call: sayGoodbye
Goodbye!
After method call: sayGoodbye
Proxy
ক্লাস ডাইনামিকভাবে প্রক্সি অবজেক্ট তৈরি করতে সাহায্য করে, যা বিভিন্ন ধরনের কাস্টম আচরণ যুক্ত করতে সক্ষম।Proxy
ক্লাসের মাধ্যমে আপনি AOP কনসেপ্ট বাস্তবায়ন করতে পারেন, যা লোগিং, সিকিউরিটি চেক, ট্রানজ্যাকশন ম্যানেজমেন্ট ইত্যাদি ক্রস-কাটিং কনসার্ন (cross-cutting concern) সহজে বাস্তবায়ন করতে সাহায্য করে।Proxy
ক্লাস ব্যবহার করে ডাইনামিক প্রক্সি অবজেক্ট তৈরি করে এবং বিভিন্ন মেথড কলের উপরে কাস্টম কার্যকারিতা (custom behavior) প্রয়োগ করে।Proxy
ব্যবহারের ফলে কোড কিছুটা জটিল হতে পারে, কারণ প্রক্সি অবজেক্টের মধ্যে অতিরিক্ত লোগিক বা আচরণ ইনজেক্ট করা হয়।Proxy Class Java-তে ডাইনামিক প্রোগ্রামিং এবং AOP (Aspect-Oriented Programming) কনসেপ্টের জন্য একটি শক্তিশালী টুল। এটি কাস্টম মেথড কল হ্যান্ডলিং, ট্রানজ্যাকশন ম্যানেজমেন্ট, লগিং ইত্যাদি কাজ করতে ব্যবহৃত হয়। তবে, এর পারফরম্যান্স এবং কোড জটিলতা সম্পর্কিত কিছু সীমাবদ্ধতা রয়েছে, যা ব্যবহারের পূর্বে সাবধানে বিবেচনা করা উচিত।
java.lang.reflect.Proxy
ক্লাসটি জাভার রিফ্লেকশন প্যাকেজের একটি গুরুত্বপূর্ণ অংশ, যা ডাইনামিক প্রক্সি অবজেক্ট তৈরি করতে সাহায্য করে। ডাইনামিক প্রক্সি একটি বিশেষ ধরনের ক্লাস বা অবজেক্ট যা রানটাইমে তৈরি করা হয় এবং এটি একটি বা একাধিক ইন্টারফেস ইমপ্লিমেন্ট করে। এটি জাভাতে রিফ্লেকশন ব্যবহার করে প্রোগ্রামের মধ্যে বিশেষভাবে সুবিধাজনক প্যাটার্ন এবং নকশা (Design Pattern) তৈরি করার জন্য ব্যবহৃত হয়, যেমন Proxy Pattern।
প্রক্সি প্যাটার্ন হল একটি স্ট্রাকচারাল ডিজাইন প্যাটার্ন যেখানে একটি অবজেক্টের জন্য এক্সেস কন্ট্রোল বা পরিষেবা প্রদানকারী হিসেবে আরেকটি অবজেক্ট ব্যবহৃত হয়। এর মাধ্যমে একটি অবজেক্টের কাজ বা পরিষেবাকে অন্য একটি অবজেক্ট দ্বারা প্রতিস্থাপন করা হয়, যা আসল অবজেক্টের কার্যকারিতা বা আচরণ পরিবর্তন না করেই কাজ করতে সক্ষম হয়।
Proxy
ক্লাসের মাধ্যমে আপনি রানটাইমে ডাইনামিকভাবে প্রক্সি অবজেক্ট তৈরি করতে পারেন যা ঐ ক্লাসের ইন্টারফেস ইমপ্লিমেন্ট করে এবং কোনও বাস্তব মেথড কল করার আগে বা পরে বিশেষ কিছু কাজ করতে পারে, যেমন লগিং, ট্রানজেকশন ম্যানেজমেন্ট, নিরাপত্তা চেক ইত্যাদি।
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
:loader
: প্রক্সি ক্লাস লোড করার জন্য ক্লাসলোডার।interfaces
: যেসব ইন্টারফেস প্রক্সি ক্লাসটি ইমপ্লিমেন্ট করবে।h
: InvocationHandler
অবজেক্ট যা মেথড কল করার সময় প্রোসেসিং করবে।InvocationHandler
Interface:InvocationHandler
ইন্টারফেসটি আপনার কাস্টম প্রক্সি অবজেক্টের আচরণ নির্ধারণ করতে ব্যবহৃত হয়। এই ইন্টারফেসের একটি মেথড invoke()
থাকে, যেটি প্রক্সি অবজেক্টে মেথড কল করার সময় কল হয়।InvocationHandler
Interface:InvocationHandler
একটি ইন্টারফেস যার একমাত্র মেথড হচ্ছে:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
proxy
: ডাইনামিক প্রক্সি অবজেক্ট।method
: যেই মেথডটি কল করা হচ্ছে তার তথ্য।args
: মেথডের আর্গুমেন্টগুলি।ধরা যাক, আমরা একটি ইন্টারফেস Hello
তৈরি করব এবং একটি প্রক্সি অবজেক্ট তৈরি করব, যা Hello
ইন্টারফেসের মেথড কল করার সময় একটি অতিরিক্ত প্রক্রিয়া (যেমন লগিং) সম্পাদন করবে।
public interface Hello {
void sayHello(String name);
}
InvocationHandler
ইমপ্লিমেন্টেশন তৈরি:import java.lang.reflect.*;
public class HelloInvocationHandler implements InvocationHandler {
private Object target;
public HelloInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// আগে কিছু কাজ করতে হবে (যেমন লগিং)
System.out.println("Method " + method.getName() + " is called");
// আসল মেথড কল করা
Object result = method.invoke(target, args);
// পরেও কিছু কাজ করতে হবে (যেমন লগিং)
System.out.println("Method " + method.getName() + " finished");
return result;
}
}
public class ProxyExample {
public static void main(String[] args) {
// আসল অবজেক্ট তৈরি
Hello realHello = new Hello() {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
};
// InvocationHandler তৈরি
HelloInvocationHandler handler = new HelloInvocationHandler(realHello);
// প্রক্সি অবজেক্ট তৈরি
Hello proxyHello = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(),
new Class[] { Hello.class },
handler
);
// প্রক্সি মেথড কল করা
proxyHello.sayHello("John");
}
}
Method sayHello is called
Hello, John
Method sayHello finished
Hello
ইন্টারফেস: এটি একটি সাধারণ ইন্টারফেস যার মধ্যে একটি মেথড sayHello()
রয়েছে।HelloInvocationHandler
: এই ক্লাসটি InvocationHandler
ইন্টারফেস ইমপ্লিমেন্ট করে এবং একটি আসল অবজেক্টের মেথড কল করার আগে এবং পরে কিছু অতিরিক্ত কাজ (যেমন লগিং) করে।Proxy.newProxyInstance()
: এটি একটি নতুন প্রক্সি অবজেক্ট তৈরি করে যা Hello
ইন্টারফেস ইমপ্লিমেন্ট করে এবং HelloInvocationHandler
এর মাধ্যমে অতিরিক্ত কার্য সম্পাদন করে।Proxy
ক্লাসের মাধ্যমে আপনি বিভিন্ন ইন্টারফেসের জন্য এক্সটেনশিবিলিটি তৈরি করতে পারেন, যা আপনার অ্যাপ্লিকেশনকে আরও ফ্লেক্সিবল করে তোলে।InvocationHandler
এর মাধ্যমে মেথড কল করা কিছুটা ধীর গতির হতে পারে, বিশেষত যখন প্রচুর সংখ্যক মেথড কল হয়।java.lang.reflect.Proxy
ক্লাসটি একটি অত্যন্ত শক্তিশালী টুল যা আপনাকে রানটাইমে ডাইনামিক প্রক্সি অবজেক্ট তৈরি করতে দেয়। এটি বিভিন্ন পরিস্থিতিতে ব্যবহৃত হতে পারে, যেমন লগিং, ট্রানজেকশন ম্যানেজমেন্ট, বা নিরাপত্তা চেক ইত্যাদি কার্য সম্পাদনের জন্য। ডাইনামিক প্রক্সি ব্যবহারের মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনকে আরও ফ্লেক্সিবল এবং কার্যকরী করতে পারেন, তবে এর পারফরম্যান্স এবং জটিলতার বিষয়ে সাবধান থাকা উচিত।
Java Reflection API-তে Dynamic Proxy একটি শক্তিশালী ফিচার যা আপনাকে একটি ইন্টারফেসের জন্য রানটাইমে প্রক্সি ক্লাস তৈরি করতে সাহায্য করে। এই প্রক্রিয়ায়, আপনি কোনও ইন্টারফেসের জন্য একটি ডাইনামিক প্রক্সি তৈরি করতে পারেন, যা একটি নির্দিষ্ট InvocationHandler
ব্যবহার করে কাজ করে। InvocationHandler
ইন্টারফেসটি ইমপ্লিমেন্ট করে আপনি সেই প্রক্সির মেথডগুলির আচরণ কাস্টমাইজ করতে পারেন।
InvocationHandler
নির্ধারণ করে, যা মেথড কল হওয়ার সময় কাস্টম আচরণ নির্ধারণ করে।InvocationHandler
একটি ইন্টারফেস, যার একটি মেথড রয়েছে: invoke()
, যা আপনাকে প্রক্সি ক্লাসের মেথড কল করার সময় কাস্টম কোড লেখার সুযোগ দেয়।InvocationHandler
ইন্টারফেসের মেথড:Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
proxy
: এটি প্রক্সি অবজেক্ট।method
: এটি মেথড অবজেক্ট যা কল করা হয়েছে।args
: এটি মেথডের প্যারামিটারগুলোর মানের অ্যারে।ধরা যাক, আমাদের একটি Hello
ইন্টারফেস আছে এবং আমরা একটি প্রক্সি ক্লাস তৈরি করতে চাই যা Hello
ইন্টারফেস ইমপ্লিমেন্ট করবে। আমরা InvocationHandler
ব্যবহার করে কাস্টম আচরণ নির্ধারণ করব।
Hello
ইন্টারফেস তৈরি করাpublic interface Hello {
void sayHello(String name);
}
InvocationHandler
ইমপ্লিমেন্টেশনimport java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloInvocationHandler implements InvocationHandler {
private final Object target;
public HelloInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method call: " + method.getName());
// যদি প্রক্সি অবজেক্টে কোন মেথড কল করা হয়, তবে টার্গেট অবজেক্টে সেই মেথড কল হবে
Object result = method.invoke(target, args);
System.out.println("After method call: " + method.getName());
return result;
}
}
Hello
ইন্টারফেসের একটি কনক্রিট ক্লাস তৈরি করাpublic class HelloImpl implements Hello {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name + "!");
}
}
import java.lang.reflect.Proxy;
public class DynamicProxyExample {
public static void main(String[] args) {
// HelloImpl ক্লাসের অবজেক্ট তৈরি
Hello realHello = new HelloImpl();
// InvocationHandler তৈরি করা
InvocationHandler handler = new HelloInvocationHandler(realHello);
// Dynamic Proxy তৈরি করা
Hello proxyHello = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(),
new Class<?>[] { Hello.class },
handler
);
// প্রক্সি অবজেক্টের মাধ্যমে মেথড কল করা
proxyHello.sayHello("John");
}
}
Hello
ইন্টারফেস:Hello
ইন্টারফেস তৈরি করা হয়েছে, যার একটি মেথড sayHello
রয়েছে।HelloInvocationHandler
ক্লাস:InvocationHandler
ইমপ্লিমেন্ট করে, এখানে invoke()
মেথডে আমরা প্রক্সি মেথড কলের আগে এবং পরে কিছু কাস্টম লজিক যোগ করেছি। method.invoke(target, args)
কলটি মূল HelloImpl
ক্লাসের মেথডটিকে কল করবে।HelloImpl
ক্লাস:Hello
ইন্টারফেসের একটি কনক্রিট ক্লাস, যা sayHello
মেথডের বাস্তবায়ন প্রদান করে।DynamicProxyExample
ক্লাস:Proxy.newProxyInstance()
মেথড ব্যবহার করে Hello
ইন্টারফেসের একটি ডাইনামিক প্রক্সি তৈরি করা হয়েছে।newProxyInstance()
মেথডে আমরা:Hello.class.getClassLoader()
: ক্লাসলোডার প্রদান করি।new Class<?>[] { Hello.class }
: ইন্টারফেসের অ্যারে প্রদান করি।handler
: InvocationHandler
প্রদান করি।proxyHello.sayHello("John");
কল করার পর, এটি প্রথমে HelloInvocationHandler
এর invoke()
মেথডে চলে যাবে এবং তারপর মূল sayHello
মেথডটি কল হবে।Before method call: sayHello
Hello, John!
After method call: sayHello
Java Reflection API এর Dynamic Proxy এবং InvocationHandler
ক্লাস Java প্রোগ্রামিংয়ে অত্যন্ত শক্তিশালী টুল। এগুলি আপনাকে runtime-এ ইন্টারফেসের জন্য প্রক্সি তৈরি করতে এবং সেই প্রক্সির মেথডগুলির আচরণ কাস্টমাইজ করতে সাহায্য করে। এটি অনেক ফ্রেমওয়ার্ক এবং লাইব্রেরির ভিতরে ব্যবহৃত একটি গুরুত্বপূর্ণ প্রযুক্তি, যা ডাইনামিক কোডিং এবং ফ্লেক্সিবল সিস্টেম ডিজাইন করতে সক্ষম।
Java রিফ্লেকশন প্যাকেজের মাধ্যমে আপনি রানটাইমে একটি ইন্টারফেসের ইমপ্লিমেন্টেশন তৈরি এবং তার মেথডগুলো ডাইনামিকভাবে কল করতে পারেন। এটি সাধারণত ডাইনামিক প্রোক্সি (Dynamic Proxy) তৈরি করতে ব্যবহৃত হয়, যেখানে আপনি রানটাইমে কোনো ক্লাস বা ইন্টারফেসের বাস্তবায়ন তৈরি করতে পারেন।
এখানে Dynamic Proxy ব্যবহারের মাধ্যমে রানটাইমে ইন্টারফেস ইমপ্লিমেন্ট করার প্রক্রিয়া ব্যাখ্যা করা হয়েছে।
Java রিফ্লেকশন প্যাকেজের java.lang.reflect.Proxy
ক্লাস এবং InvocationHandler
ইন্টারফেসের সাহায্যে আপনি রানটাইমে একটি ইন্টারফেস ইমপ্লিমেন্ট করতে পারেন।
Proxy
ক্লাসটি একটি ডাইনামিক প্রোক্সি অবজেক্ট তৈরি করতে ব্যবহৃত হয়, যা একটি বা একাধিক ইন্টারফেস ইমপ্লিমেন্ট করে। InvocationHandler
ইন্টারফেসটি বাস্তবায়ন করে আপনি প্রোক্সি অবজেক্টের মেথড কলিং এর আচরণ নির্ধারণ করতে পারেন।
InvocationHandler
ইন্টারফেসের মাধ্যমে, আপনি সেই মেথডগুলো ডাইনামিকভাবে হ্যান্ডেল করতে পারবেন যা প্রোক্সি অবজেক্টের মাধ্যমে কল করা হয়।
InvocationHandler
ইন্টারফেসের মাধ্যমে আপনি মেথড কলের আচরণ কাস্টমাইজ করবেন।Proxy.newProxyInstance()
মেথড ব্যবহার করে ডাইনামিক প্রোক্সি অবজেক্ট তৈরি করবেন।এখানে একটি উদাহরণ দেওয়া হলো, যেখানে একটি MyInterface
ইন্টারফেস রানটাইমে ইমপ্লিমেন্ট করা হয়েছে এবং তার মেথড কল করা হয়েছে:
import java.lang.reflect.*;
interface MyInterface {
void sayHello(String name);
int addNumbers(int a, int b);
}
public class DynamicProxyExample {
public static void main(String[] args) {
// InvocationHandler তৈরি করা
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// মেথডের নাম চেক করে কাজ করা
if (method.getName().equals("sayHello")) {
System.out.println("Hello, " + args[0]);
return null; // sayHello() মেথডের জন্য কোন রিটার্ন নেই
} else if (method.getName().equals("addNumbers")) {
int result = (int) args[0] + (int) args[1];
System.out.println("Addition Result: " + result);
return result; // addNumbers() মেথডের জন্য যোগফল রিটার্ন
}
return null;
}
};
// Proxy তৈরি করা
MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class<?>[]{MyInterface.class},
handler
);
// প্রোক্সি অবজেক্টের মেথড কল
proxyInstance.sayHello("John");
int sum = proxyInstance.addNumbers(10, 20);
System.out.println("Returned Sum: " + sum);
}
}
MyInterface
ইন্টারফেসটি দুটি মেথড sayHello()
এবং addNumbers()
ধারণ করে।InvocationHandler
ইন্টারফেসটি একটি invoke()
মেথড সাপোর্ট করে, যা প্রোক্সি অবজেক্টের মেথড কল করার সময় কল হয়। এখানে, আমরা মেথডের নাম চেক করে তার আচরণ কাস্টমাইজ করেছি।Proxy.newProxyInstance()
ব্যবহার করে আমরা একটি ডাইনামিক প্রোক্সি অবজেক্ট তৈরি করেছি যা MyInterface
ইন্টারফেসটি ইমপ্লিমেন্ট করে।sayHello()
এবং addNumbers()
মেথডগুলো কল করা হয়েছে। sayHello()
মেথডের জন্য একটি বার্তা প্রিন্ট হয়েছে এবং addNumbers()
মেথডের জন্য যোগফল রিটার্ন হয়েছে।Proxy
এবং InvocationHandler
এর মাধ্যমে স্ট্যান্ডার্ড API ব্যবহার করে ডাইনামিক প্রোক্সি তৈরি করা সম্ভব।Java রিফ্লেকশন প্যাকেজের মাধ্যমে ডাইনামিক প্রোক্সি ব্যবহারের মাধ্যমে আপনি রানটাইমে ইন্টারফেস ইমপ্লিমেন্ট করতে পারেন। এটি বিভিন্ন প্রোগ্রামিং প্যাটার্ন যেমন AOP (Aspect-Oriented Programming) ইমপ্লিমেন্ট করতে সহায়ক, যেখানে আপনি মেথড কলের আচরণ পরিবর্তন করতে পারেন। তবে, এটি কিছু পারফরম্যান্স ইস্যু এবং কোড জটিলতা সৃষ্টি করতে পারে, তাই এটি সাবধানে ব্যবহার করা উচিত।
Read more