Hot Deployment of Java Interface Implementations Using Reflection and Spring

This article explains how to let users upload a JAR that implements a predefined Java interface, then dynamically load, register, and switch the implementation at runtime using both reflection‑based and Spring‑annotation‑based hot‑deployment techniques, complete with code examples and utility methods.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Hot Deployment of Java Interface Implementations Using Reflection and Spring

During development a system may require a user‑provided implementation of a given interface; the user packages the implementation into a JAR, uploads it, and the system hot‑deploys the new implementation without restarting.

Define a simple interface – the example uses a Calculator interface with int calculate(int a, int b) and int add(int a, int b) methods:

public interface Calculator {
    int calculate(int a, int b);
    int add(int a, int b);
}

Implementation class – two approaches are shown: an annotation‑based method ( calculate) and a reflection‑based method ( add). The class injects CalculatorCore and implements both methods.

@Service
public class CalculatorImpl implements Calculator {
    @Autowired
    CalculatorCore calculatorCore;

    /** Annotation‑based */
    @Override
    public int calculate(int a, int b) {
        int c = calculatorCore.add(a, b);
        return c;
    }

    /** Reflection‑based */
    @Override
    public int add(int a, int b) {
        return new CalculatorCore().add(a, b);
    }
}

The supporting CalculatorCore simply returns the sum of two integers:

@Service
public class CalculatorCore {
    public int add(int a, int b) {
        return a + b;
    }
}

Reflection‑based hot deployment – the uploaded JAR path is defined, then the JAR is loaded with a URLClassLoader, the implementation class is instantiated via reflection, and its method is invoked:

private static String jarAddress = "E:/zzq/IDEA_WS/CalculatorTest/lib/Calculator.jar";
private static String jarPath = "file:/" + jarAddress;

/** Hot load Calculator implementation via reflection */
public static void hotDeployWithReflect() throws Exception {
    URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());
    Class clazz = urlClassLoader.loadClass("com.nci.cetc15.calculator.impl.CalculatorImpl");
    Calculator calculator = (Calculator) clazz.newInstance();
    int result = calculator.add(1, 2);
    System.out.println(result);
}

Annotation‑based hot deployment – if the uploaded JAR contains Spring components, the system scans all classes, identifies those with Spring annotations, and registers them into the current Spring container dynamically:

/** Register beans from uploaded JAR into Spring */
public static void hotDeployWithSpring() throws Exception {
    Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
    URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());
    for (String className : classNameSet) {
        Class clazz = urlClassLoader.loadClass(className);
        if (DeployUtils.isSpringBeanClass(clazz)) {
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
            defaultListableBeanFactory.registerBeanDefinition(DeployUtils.transformName(className), beanDefinitionBuilder.getBeanDefinition());
        }
    }
}

The utility class DeployUtils provides three methods:

/** Read all class files from a JAR */
public static Set<String> readJarFile(String jarAddress) throws IOException { ... }

/** Determine whether a class has a Spring stereotype annotation */
public static boolean isSpringBeanClass(Class<?> cla) { ... }

/** Convert the class name to a bean name (lower‑case first letter) */
public static String transformName(String className) { ... }

Removing a JAR – when a JAR is deleted or replaced, the previously registered Spring beans must be removed from the container using the same bean names:

/** Delete beans of an uploaded JAR from Spring */
public static void delete() throws Exception {
    Set<String> classNameSet = DeployUtils.readJarFile(jarAddress);
    URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());
    for (String className : classNameSet) {
        Class clazz = urlClassLoader.loadClass(className);
        if (DeployUtils.isSpringBeanClass(clazz)) {
            defaultListableBeanFactory.removeBeanDefinition(DeployUtils.transformName(className));
        }
    }
}

Testing – a test loop continuously attempts to hot‑deploy the JAR; if the JAR is not yet present, an exception is caught and the thread sleeps, allowing the developer to place the JAR in the designated directory.

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
while (true) {
    try {
        hotDeployWithReflect();
        // hotDeployWithSpring();
        // delete();
    } catch (Exception e) {
        e.printStackTrace();
        Thread.sleep(1000 * 10);
    }
}

Source: https://blog.csdn.net/zhangzhiqiang_0912

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaReflectionspringDynamic LoadingHot Deployment
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.