java 动态加载bean_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启动类:

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 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);

}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值