springboot手动动态注入controller和service
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.FileSystemResourceLoader;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@SpringBootApplication
@Component
public class ApplicationBootstrap {
static ApplicationContext applicationContext;
static String file = "F:\\download\\apache-maven-3.3.9-bin\\repository\\org\\example\\springboot-test-common\\1.0-SNAPSHOT\\" +
"springboot-test-common-1.0-SNAPSHOT.jar";
public static void main(String[] args) throws Exception {
applicationContext = SpringApplication.run(ApplicationBootstrap.class, args);
String clazzName = "test1.controller.MyTestController1";
String clazzName1 = "test1.service.MyTestServiceImpl";
registerBean(clazzName1);
registerBean(clazzName);
registerController(StringUtils.uncapitalize(clazzName.substring(clazzName.lastIndexOf(".") + 1)));
}
public static void registerBean(String clazzName) throws Exception{
URL url = new File(file).toURI().toURL();
// URLClassLoader loader = (URLClassLoader) ApplicationBootstrap.class.getClassLoader();
// Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
// add.setAccessible(true);
// add.invoke(loader, url);
URLClassLoader loader = new URLClassLoader(new URL[]{url});
// String clazzName = "test1.controller.MyTestController1";
Class<?> clazz = loader.loadClass(clazzName);
// applicationContext.getClassLoader().loadClass("test.MyController");
// DefaultListableBeanFactory factory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
//设置当前bean定义对象是单利的
beanDefinition.setScope("singleton");
//将变量首字母置小写
String beanName = StringUtils.uncapitalize(clazzName);
beanName = beanName.substring(beanName.lastIndexOf(".")+1);
beanName = StringUtils.uncapitalize(beanName);
//将applicationContext转换为ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
// 获取bean工厂并转换为DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinition);
}
/**
* 注册Controller
* @param controllerBeanName
* @throws Exception
*/
public static void registerController(String controllerBeanName) throws Exception{
final RequestMappingHandlerMapping requestMappingHandlerMapping=
applicationContext.getBean(RequestMappingHandlerMapping.class);
if(requestMappingHandlerMapping!=null){
String handler=controllerBeanName;
Object controller= applicationContext.getBean(handler);
if(controller==null){
return;
}
// unregisterController(controllerBeanName);
//注册Controller
Method method=requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().
getDeclaredMethod("detectHandlerMethods",Object.class);
//将private改为可使用
method.setAccessible(true);
method.invoke(requestMappingHandlerMapping,handler);
}
}
/**
* 去掉Controller的Mapping
* @param controllerBeanName
*/
public static void unregisterController(String controllerBeanName){
final RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping)
applicationContext.getBean("requestMappingHandlerMapping");
if(requestMappingHandlerMapping!=null){
String handler=controllerBeanName;
Object controller= applicationContext.getBean(handler);
if(controller==null){
return;
}
final Class<?> targetClass=controller.getClass();
ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
try {
Method createMappingMethod = RequestMappingHandlerMapping.class.
getDeclaredMethod("getMappingForMethod", Method.class, Class.class);
createMappingMethod.setAccessible(true);
RequestMappingInfo requestMappingInfo =(RequestMappingInfo)
createMappingMethod.invoke(requestMappingHandlerMapping,specificMethod,targetClass);
if(requestMappingInfo != null) {
requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
}
}catch (Exception e){
e.printStackTrace();
}
}
}, ReflectionUtils.USER_DECLARED_METHODS);
}
}
}
引用
- https://bbs.csdn.net/topics/392073765
- https://blog.csdn.net/w757227129/article/details/93166401?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-2