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); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。