首页 > 编程 > Java > 正文

Spring动态加载bean后调用实现方法解析

2019-11-26 08:41:25
字体:
来源:转载
供稿:网友

前言

在使用Spring的过程中,我们有时候并不想通过xml的方式进行bean的注入,希望在不改变原有的程序结构的基础上添加我们需要的bean,这个时候我们可以利用Spring的spring-beans的jar包里提供的BeanFactoryPostProcessor接口类,通过实现这个接口类,我们可以动态的加载所需要的bean,特别是在引入已经打包在jar里面的程序而没有办法做出修改的情况下,这个接口就为我们提供了及其方便的入口。

因为我是在其他项目的基础上测试的这个接口,所以引入的jar有其特殊性,所以需要参考的同学可以按照自己的需求来实现。

1.通过pom.xml来引入springboot:

<parent>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-parent</artifactId>   <version>1.5.6.RELEASE</version>  </parent>  <dependencies>   <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-test</artifactId>   </dependency>   <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>   </dependency>   <dependency>    <groupId>com.thread</groupId>    <artifactId>test</artifactId>    <version>1.0</version>    <scope>system</scope>    <systemPath>f:/threadTest.jar</systemPath>   </dependency>  </dependencies> 

2.创建App.java启动类:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /**  * @author liaoyubo  * @version 1.0 2017/7/31  * @description  */ @SpringBootApplication public class App {   public static void main(String [] args){   SpringApplication.run(App.class);  } } 

3.创建一个DynamicCreateBean.java来作为动态加载的对象:

public class DynamicCreateBean {  public void printMethod(){   System.out.println("DynamicCreateBean Success");  } }

4.在本项目外另外新增一个项目打成jar的形式导入到该项目中用于测试动态加载,在我的项目中新增的是threadTest.jar,该包是一个用于多线程测试的类,需要的同学自己随便新建一个来打成jar包测试即可。

5.新增一个LoadBean.java类用于动态加载bean:

import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.stereotype.Component; import com.thread.mulitSynThreadTest.Run; /**  * @author liaoyubo  * @version 1.0 2017/8/11  * @description  */ @Component public class LoadBean implements BeanFactoryPostProcessor {  private DefaultListableBeanFactory defaultListableBeanFactory;  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {   this.defaultListableBeanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;   BeanDefinitionBuilder beanDefinitionBuilder = 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.创建测试类:

import com.springRedis.App; import com.springRedis.dynamic.DynamicCreateBean; import com.thread.mulitSynThreadTest.Run; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /**  * @author liaoyubo  * @version 1.0 2017/8/11  * @description  */ @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class MultiTest {  @Autowired  private DynamicCreateBean dynamicCreateBean;  @Autowired  private Run run;  @Test  public void testDynamic(){   dynamicCreateBean.printMethod();   run.printRun();  } } 

以上就是整个的动态加载过程,如果需要了解更多,可以在网上继续查找资料。

最近在看spring cloud Feign相关文章时发现了另外一种注入动态bean的方式,里面的代码提供是在FeignClientsRegistrar.java类中

具体代码为:

private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {   String className = annotationMetadata.getClassName();   BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);   this.validate(attributes);   definition.addPropertyValue("url", this.getUrl(attributes));   definition.addPropertyValue("path", this.getPath(attributes));   String name = 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);   String alias = name + "FeignClient";   AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();   boolean primary = ((Boolean)attributes.get("primary")).booleanValue();   beanDefinition.setPrimary(primary);   String qualifier = this.getQualifier(attributes);   if(StringUtils.hasText(qualifier)) {    alias = qualifier;   }   BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias});   BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);  } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表