Dynamic Proxy তৈরি করা এবং InvocationHandler ব্যবহার

Proxy এবং Dynamic Proxy Class - জাভা রিফ্লেক্ট প্যাকেজ (Java.reflect Package) - Java Technologies

257

Java Reflection API-তে Dynamic Proxy একটি শক্তিশালী ফিচার যা আপনাকে একটি ইন্টারফেসের জন্য রানটাইমে প্রক্সি ক্লাস তৈরি করতে সাহায্য করে। এই প্রক্রিয়ায়, আপনি কোনও ইন্টারফেসের জন্য একটি ডাইনামিক প্রক্সি তৈরি করতে পারেন, যা একটি নির্দিষ্ট InvocationHandler ব্যবহার করে কাজ করে। InvocationHandler ইন্টারফেসটি ইমপ্লিমেন্ট করে আপনি সেই প্রক্সির মেথডগুলির আচরণ কাস্টমাইজ করতে পারেন।

Dynamic Proxy এবং InvocationHandler এর ব্যবহার:

  1. Dynamic Proxy:
    • Dynamic Proxy আপনাকে রানটাইমে একটি নতুন ক্লাস তৈরি করতে দেয় যা একটি নির্দিষ্ট ইন্টারফেস ইমপ্লিমেন্ট করে। এটি সেই ইন্টারফেসের সমস্ত মেথডের জন্য InvocationHandler নির্ধারণ করে, যা মেথড কল হওয়ার সময় কাস্টম আচরণ নির্ধারণ করে।
  2. InvocationHandler:
    • InvocationHandler একটি ইন্টারফেস, যার একটি মেথড রয়েছে: invoke(), যা আপনাকে প্রক্সি ক্লাসের মেথড কল করার সময় কাস্টম কোড লেখার সুযোগ দেয়।

InvocationHandler ইন্টারফেসের মেথড:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
  • proxy: এটি প্রক্সি অবজেক্ট।
  • method: এটি মেথড অবজেক্ট যা কল করা হয়েছে।
  • args: এটি মেথডের প্যারামিটারগুলোর মানের অ্যারে।

Dynamic Proxy তৈরি করার উদাহরণ:

ধরা যাক, আমাদের একটি Hello ইন্টারফেস আছে এবং আমরা একটি প্রক্সি ক্লাস তৈরি করতে চাই যা Hello ইন্টারফেস ইমপ্লিমেন্ট করবে। আমরা InvocationHandler ব্যবহার করে কাস্টম আচরণ নির্ধারণ করব।

Step 1: Hello ইন্টারফেস তৈরি করা

public interface Hello {
    void sayHello(String name);
}

Step 2: 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;
    }
}

Step 3: Hello ইন্টারফেসের একটি কনক্রিট ক্লাস তৈরি করা

public class HelloImpl implements Hello {
    @Override
    public void sayHello(String name) {
        System.out.println("Hello, " + name + "!");
    }
}

Step 4: Dynamic Proxy তৈরি করা এবং ব্যবহার করা

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");
    }
}

কোড বিশ্লেষণ:

  1. Hello ইন্টারফেস:
    • এখানে একটি সাধারণ Hello ইন্টারফেস তৈরি করা হয়েছে, যার একটি মেথড sayHello রয়েছে।
  2. HelloInvocationHandler ক্লাস:
    • InvocationHandler ইমপ্লিমেন্ট করে, এখানে invoke() মেথডে আমরা প্রক্সি মেথড কলের আগে এবং পরে কিছু কাস্টম লজিক যোগ করেছি। method.invoke(target, args) কলটি মূল HelloImpl ক্লাসের মেথডটিকে কল করবে।
  3. HelloImpl ক্লাস:
    • এটি Hello ইন্টারফেসের একটি কনক্রিট ক্লাস, যা sayHello মেথডের বাস্তবায়ন প্রদান করে।
  4. DynamicProxyExample ক্লাস:
    • এখানে Proxy.newProxyInstance() মেথড ব্যবহার করে Hello ইন্টারফেসের একটি ডাইনামিক প্রক্সি তৈরি করা হয়েছে।
    • newProxyInstance() মেথডে আমরা:
      • Hello.class.getClassLoader(): ক্লাসলোডার প্রদান করি।
      • new Class<?>[] { Hello.class }: ইন্টারফেসের অ্যারে প্রদান করি।
      • handler: InvocationHandler প্রদান করি।
  5. প্রক্সি অবজেক্টে মেথড কল:
    • proxyHello.sayHello("John"); কল করার পর, এটি প্রথমে HelloInvocationHandler এর invoke() মেথডে চলে যাবে এবং তারপর মূল sayHello মেথডটি কল হবে।

আউটপুট:

Before method call: sayHello
Hello, John!
After method call: sayHello

Dynamic Proxy এর সুবিধা:

  1. ডাইনামিক মেথড রাউটিং: আপনি প্রক্সি অবজেক্টের মাধ্যমে একটি নির্দিষ্ট মেথডের কাস্টম আচরণ বা লজিক যুক্ত করতে পারেন।
  2. কমপ্লেক্স ফ্রেমওয়ার্ক: এই প্রক্রিয়াটি অনেক Java ফ্রেমওয়ার্ক (যেমন Spring, Hibernate) এ ব্যবহৃত হয় যেখানে ডাইনামিক প্রক্সি ব্যবহার করে মেথড কল হ্যান্ডল করা হয়।
  3. মডুলার কোড: বিভিন্ন মেথড কলের জন্য আলাদা কাস্টম আচরণ তৈরি করা সম্ভব, যা কোডকে আরও মডুলার এবং রিইউজেবল করে তোলে।

Java Reflection API এর Dynamic Proxy এবং InvocationHandler ক্লাস Java প্রোগ্রামিংয়ে অত্যন্ত শক্তিশালী টুল। এগুলি আপনাকে runtime-এ ইন্টারফেসের জন্য প্রক্সি তৈরি করতে এবং সেই প্রক্সির মেথডগুলির আচরণ কাস্টমাইজ করতে সাহায্য করে। এটি অনেক ফ্রেমওয়ার্ক এবং লাইব্রেরির ভিতরে ব্যবহৃত একটি গুরুত্বপূর্ণ প্রযুক্তি, যা ডাইনামিক কোডিং এবং ফ্লেক্সিবল সিস্টেম ডিজাইন করতে সক্ষম।

Content added By
Promotion

Are you sure to start over?

Loading...