package org.hotswap.agent.plugin.spring.scanner;
import org.hotswap.agent.annotation.OnClassLoadEvent;
import org.hotswap.agent.javassist.*;
import org.hotswap.agent.logging.AgentLogger;
/**
* Hook into classpath scanner process to register basicPackage of scanned classes.
*
* Catch changes on component-scan configuration such as (see tests):
* <pre><context:component-scan base-package="org.hotswap.agent.plugin.spring.testBeans"/></pre>
*/
public class ClassPathBeanDefinitionScannerTransformer {
private static AgentLogger LOGGER = AgentLogger.getLogger(ClassPathBeanDefinitionScannerTransformer.class);
/**
* Insert at the beginning of the method:
* <pre>public Set<BeanDefinition> findCandidateComponents(String basePackage)</pre>
* new code to initialize ClassPathBeanDefinitionScannerAgent for a base class
* It would be better to override a more appropriate method
* org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan() directly,
* however there are issues with javassist and varargs parameters.
*/
@OnClassLoadEvent(classNameRegexp = "org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider")
public static void transform(CtClass clazz, ClassPool classPool) throws NotFoundException, CannotCompileException {
CtMethod method = clazz.getDeclaredMethod("findCandidateComponents", new CtClass[]{classPool.get("java.lang.String")});
method.insertAfter("if (this instanceof org.springframework.context.annotation.ClassPathBeanDefinitionScanner) {" +
"org.hotswap.agent.plugin.spring.scanner.ClassPathBeanDefinitionScannerAgent." +
"getInstance((org.springframework.context.annotation.ClassPathBeanDefinitionScanner)this)." +
"registerBasePackage($1);" +
"}");
LOGGER.debug("Class 'org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider' patched with basePackage registration.");
}
}