import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.stereotype.Component;
import java.util.function.Supplier;
/**
* @author qbit
*/
@Component
public class ControllerRegistry implements BeanDefinitionRegistryPostProcessor {
private DynamicCompiler compiler;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
SrcGenerator srcGenerator=new SrcGenerator();
new ControllerScanner().controllers()
.forEach(clazz->{
if(null==compiler){
compiler=new DynamicCompiler(clazz.getClassLoader());
}
final String className=srcGenerator.implClassName(clazz);
final String name= StringUtils.substringAfterLast(className,".");
final Class implClass=compiler.compile(className,srcGenerator.implSrc(clazz));
final Object impl= ReflectUtils.newInstance(implClass);
BeanDefinitionBuilder beanDefinitionBuilder=BeanDefinitionBuilder.genericBeanDefinition(implClass, () -> impl);
BeanDefinition beanDefinition=beanDefinitionBuilder.getBeanDefinition();
beanDefinition.setBeanClassName(className);
BeanDefinitionHolder holder=new BeanDefinitionHolder(beanDefinition,name);
BeanDefinitionReaderUtils.registerBeanDefinition(holder,beanDefinitionRegistry);
System.out.println(beanDefinition);
});
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
if(null!=compiler){
configurableListableBeanFactory.setBeanClassLoader(compiler.getClassLoader());
}
}
}