有时候,会有这样一个需求,在程序运行时动态生成的对象,需要注入到Spring容器中进行管理。
下面是获取Bean以及注入Bean的工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;
import java.lang.reflect.Field; import java.util.Map;
@Component public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtils.applicationContext = applicationContext; }
public static ApplicationContext getApplicationContext() { return applicationContext; }
public static Object getBean(String name) throws BeansException { return applicationContext.getBean(name); }
public static Object getBean(Class name) throws BeansException { return applicationContext.getBean(name); }
/** * bean注入spring容器 * map[id,className,...] * id 为 bean的标识 * className 为 类的全限定类名 * ... 为其他属性 * @param map */ public static void injectBean(Map<String, String> map) { String className = map.get( "className" ); Class<?> aClass; if (className == null ) { throw new RuntimeException( "map参数缺少className" ); }
try { aClass = Class.forName(className); if (aClass == null ) { throw new RuntimeException( "className不存在" ); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(aClass); Field[] declaredFields = aClass.getDeclaredFields(); for ( int i = 0 ; i < declaredFields.length; i++) { String fieldName = declaredFields[i].getName(); if (map.get(fieldName) != null ) { // 必须设置可访问,否则下面的操作做不了 // declaredFields[i].setAccessible(true); builder.addPropertyValue(fieldName, map.get(fieldName)); } } BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext; // 注册bean 第一个参数为 name ,第二个为 bean定义类 String id = map.get( "id" ); if (id == null ) { registry.registerBeanDefinition(className, builder.getBeanDefinition()); return ; } registry.registerBeanDefinition(id, builder.getBeanDefinition()); } } |
测试
1 2 3 4 5 6 7 8 9 10 11 |
@Test public void test2() { HashMap<String, String> map = new HashMap<>(); map.put( "id" , "helloTask" ); map.put( "className" , "com.example.demo.Task.HelloTask4" ); // 注册bean SpringUtils.injectBean(map); // HelloTask4 helloTask =(HelloTask4) SpringUtils.getBean(HelloTask4.class); HelloTask4 helloTask = (HelloTask4) SpringUtils.getBean( "helloTask" ); System.out.println(helloTask.getClass()); } |
附:利用注解向Spring容器中注入Bean
常用注解包含:@Controller、@Service、@Repository、@Component,其中@Controller、@Service、@Repository都是基于@Component的扩展。通常的@Controller用于标识处理前端请求的类,@Service用于标识业务逻辑类,@Repository用于标识DAO层的类,@Component为通用注解,可以标注在任何想要注入容器中的类上面;
1 2 3 4 5 6 7 |
@Component //@Controller //@Service //@Repository class Stu{
} |
也可以利用@Bean与@Configuration注入,其中@Configuration用于标注一个配置类,@Bean用于标注返回需注入Bean的方法;
1 2 3 4 5 6 7 |
@Configuration class MyConfig{ @Bean public Student getStudent(){ return new Student(); } } |
总结
到此这篇关于Spring运行时手动注入bean的文章就介绍到这了,更多相关Spring运行手动注入bean内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
原文链接:https://juejin.cn/post/7103444236682395655
查看更多关于Spring运行时手动注入bean的方法实例的详细内容...