《阿布的点点滴滴》:如何在程序运行期间,动态生成spring bean,并放入spring 容器中? 您所在的位置:网站首页 spring运行时注入 《阿布的点点滴滴》:如何在程序运行期间,动态生成spring bean,并放入spring 容器中?

《阿布的点点滴滴》:如何在程序运行期间,动态生成spring bean,并放入spring 容器中?

2023-08-13 06:44| 来源: 网络整理| 查看: 265

曾经在项目开发中,需要实现手动生成spring bean,并将bean交由spring容器中管理的功能,费尽脑汁无从下手。最近在看spring MVC源码时,偶然发现其有相应的解决办法,其最终通过DefaultListableBeanFactory来完成。在此小记一下解决问题的过程!

 以上是springMVC中,DispatcherServlet的diagram。其继承FrameworkServlet,FrameworkServlet继承HttpServletBean,HttpServletBean继承HttpServlet。HttpServlet属于serlvet规范,当Tomcat启动时,调用其init方法,最终调用到了DispatcherServlet的onRefresh方法。

 关键代码在onRefresh中,初始化了springMVC执行过程中需要的对象,包括HandlerMappings、HandlerAdapters等。

private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; static { try { //加载DispatcherServlet.properties中内容 ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage()); } //初始化DispatcherServlet.properties文件中的类 protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }

 DispatcherServlet.properties内容:

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

在initHandlerMappings方法中,会去完成动态生成HandlerMappingbean,具体方法:

protected Object createDefaultStrategy(ApplicationContext context, Class clazz) { return context.getAutowireCapableBeanFactory().createBean(clazz); }

通过容器获取DefaultListableBeanFactory

①调用其父类AbstractAutowireCapableBeanFactory的createBean方法,可将class对象转化为一个spring bean,并完成IOC,这也正是笔者想要实现的功能;

②DefaultListableBeanFactory中的registerSingleton方法可完成将bean注册到spring单例池中。

大功告成!!!

 当然,DefaultListableBeanFactory中还有好多功能,如getbean、注册、解析等。笔者再遇到其他用法时,后续更新。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有