Spring運行時手動註入bean的方法實例
有時候,會有這樣一個需求,在程序運行時動態生成的對象,需要註入到Spring容器中進行管理。
下面是獲取Bean以及註入Bean的工具類
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()); } }
測試
@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為通用註解,可以標註在任何想要註入容器中的類上面;
@Component //@Controller //@Service //@Repository class Stu{ }
也可以利用@Bean與@Configuration註入,其中@Configuration用於標註一個配置類,@Bean用於標註返回需註入Bean的方法;
@Configuration class MyConfig{ @Bean public Student getStudent(){ return new Student(); } }
總結
到此這篇關於Spring運行時手動註入bean的文章就介紹到這瞭,更多相關Spring運行手動註入bean內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Springboot 如何獲取上下文對象
- SpringBoot項目如何將Bean註入到普通類中
- 解決netty中spring對象註入失敗的問題
- 基於Spring上下文工具類 ApplicationContextUtil
- springboot實現在工具類(util)中調用註入service層方法