Spring动态加载bean后调用实现方法解析
前言
在使用Spring的过程中,我们有时候并不想通过xml的方式进行bean的注入,希望在不改变原有的程序结构的基础上添加我们需要的bean,这个时候我们可以利用Spring的spring-beans的jar包里提供的BeanFactoryPostProcessor接口类,通过实现这个接口类,我们可以动态的加载所需要的bean,特别是在引入已经打包在jar里面的程序而没有办法做出修改的情况下,这个接口就为我们提供了及其方便的入口。
因为我是在其他项目的基础上测试的这个接口,所以引入的jar有其特殊性,所以需要参考的同学可以按照自己的需求来实现。
1.通过pom.xml来引入springboot:
org.springframework.boot spring-boot-starter-parent 1.5.6.RELEASE org.springframework.boot spring-boot-starter-test org.springframework.boot spring-boot-starter-web com.thread test 1.0 system f:/threadTest.jar
2.创建App.java启动类:
importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; /** *@authorliaoyubo *@version1.02017/7/31 *@description */ @SpringBootApplication publicclassApp{ publicstaticvoidmain(String[]args){ SpringApplication.run(App.class); } }
3.创建一个DynamicCreateBean.java来作为动态加载的对象:
publicclassDynamicCreateBean{ publicvoidprintMethod(){ System.out.println("DynamicCreateBeanSuccess"); } }
4.在本项目外另外新增一个项目打成jar的形式导入到该项目中用于测试动态加载,在我的项目中新增的是threadTest.jar,该包是一个用于多线程测试的类,需要的同学自己随便新建一个来打成jar包测试即可。
5.新增一个LoadBean.java类用于动态加载bean:
importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanFactoryPostProcessor; importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory; importorg.springframework.beans.factory.support.BeanDefinitionBuilder; importorg.springframework.beans.factory.support.DefaultListableBeanFactory; importorg.springframework.stereotype.Component; importcom.thread.mulitSynThreadTest.Run; /** *@authorliaoyubo *@version1.02017/8/11 *@description */ @Component publicclassLoadBeanimplementsBeanFactoryPostProcessor{ privateDefaultListableBeanFactorydefaultListableBeanFactory; @Override publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactoryconfigurableListableBeanFactory)throwsBeansException{ this.defaultListableBeanFactory=(DefaultListableBeanFactory)configurableListableBeanFactory; BeanDefinitionBuilderbeanDefinitionBuilder=BeanDefinitionBuilder.rootBeanDefinition("com.springRedis.dynamic.DynamicCreateBean"); //用于设置指定的类中需要引入的其他bean //beanDefinitionBuilder.addPropertyValue("otherBeanName","otherBeanName"); this.defaultListableBeanFactory.registerBeanDefinition("dynamicCreateBean",beanDefinitionBuilder.getBeanDefinition()); beanDefinitionBuilder=BeanDefinitionBuilder.rootBeanDefinition(Run.class.getName()); //用于设置指定的类中需要引入的其他bean //beanDefinitionBuilder.addPropertyValue("otherBeanName","otherBeanName"); this.defaultListableBeanFactory.registerBeanDefinition("mulitRun",beanDefinitionBuilder.getBeanDefinition()); } }
6.创建测试类:
importcom.springRedis.App; importcom.springRedis.dynamic.DynamicCreateBean; importcom.thread.mulitSynThreadTest.Run; importorg.junit.Test; importorg.junit.runner.RunWith; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.boot.test.context.SpringBootTest; importorg.springframework.test.context.junit4.SpringRunner; /** *@authorliaoyubo *@version1.02017/8/11 *@description */ @RunWith(SpringRunner.class) @SpringBootTest(classes=App.class) publicclassMultiTest{ @Autowired privateDynamicCreateBeandynamicCreateBean; @Autowired privateRunrun; @Test publicvoidtestDynamic(){ dynamicCreateBean.printMethod(); run.printRun(); } }
以上就是整个的动态加载过程,如果需要了解更多,可以在网上继续查找资料。
最近在看springcloudFeign相关文章时发现了另外一种注入动态bean的方式,里面的代码提供是在FeignClientsRegistrar.java类中
具体代码为:
privatevoidregisterFeignClient(BeanDefinitionRegistryregistry,AnnotationMetadataannotationMetadata,Mapattributes){ StringclassName=annotationMetadata.getClassName(); BeanDefinitionBuilderdefinition=BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class); this.validate(attributes); definition.addPropertyValue("url",this.getUrl(attributes)); definition.addPropertyValue("path",this.getPath(attributes)); Stringname=this.getName(attributes); definition.addPropertyValue("name",name); definition.addPropertyValue("type",className); definition.addPropertyValue("decode404",attributes.get("decode404")); definition.addPropertyValue("fallback",attributes.get("fallback")); definition.addPropertyValue("fallbackFactory",attributes.get("fallbackFactory")); definition.setAutowireMode(2); Stringalias=name+"FeignClient"; AbstractBeanDefinitionbeanDefinition=definition.getBeanDefinition(); booleanprimary=((Boolean)attributes.get("primary")).booleanValue(); beanDefinition.setPrimary(primary); Stringqualifier=this.getQualifier(attributes); if(StringUtils.hasText(qualifier)){ alias=qualifier; } BeanDefinitionHolderholder=newBeanDefinitionHolder(beanDefinition,className,newString[]{alias}); BeanDefinitionReaderUtils.registerBeanDefinition(holder,registry); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。