想要讓自己寫的一個普通類創建的對象扔到Spring 容器中管理,有以下方法:
- 使用 常規的註解,@Controller @Service @Repository @Component 註解標註該類,然後確保 @ComponentScan 掃描路徑包含以上的類即可
- 使用 @Bean 註解的方法裏面 new 出來的對象會進入Spring容器,當然標有@Configuration 的配置類本身也會創建一個對象進入Spring容器(IOC)中的
- 使用 @ConfigurationProperties 和 @EnableConfigurationProperties 組合的用於接受yml文件中參數的類也會創建對象進入Spring容器(IOC)
- @Import 方法
YourBusinessService 是自定義的類
@Configuration
@Import(YourBusinessService.class)
public class YourBusinessImportConfig {
}
當然 可以將類 YourBusinessImportConfig 換成註解也行,例如:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({YourBusinessService.class})
public @interface EnableYourBusinessService {
}
然後你就可以在自己的Spring項目中採用 @EnableYourBusinessService 來注入 YourBusinessService對象。
- 實現ImportSelector接口方法批量注入對象
這個需要配合 @Import註解
public class YourBusinessServiceSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.baisheng.service.YourBusinessService"};
}
}
然後通過@Import註解注入到Spring容器裏面
@Configuration
@Import(YourBusinessServiceSelector .class)
public class YourBusinessImportConfig {
}
當然同理,可以將YourBusinessImportConfig 類換成註解也行
- 實現ImportBeanDefinitionRegistrar 接口方法批量注入對象
這個需要配合 @Import註解
這個方法在Spring框架中用的很多,你會發現上面的 @EnableConfigurationProperties 其實就是採用該方法將參數配置類注入spring容器中的,查看源碼如下:
public class EnableConfigurationPropertiesRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
registerInfrastructureBeans(registry);
ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry);
this.getTypes(metadata).forEach(beanRegistrar::register);
}
}
自己寫一個
public class YourBeanDefinitionRegistrat implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new RootBeanDefinition(YourBusinessService.class);
registry.registerBeanDefinition("yourBusinessService", beanDefinition);
}
}
- 採用 BeanDefinitionRegistry 動態注入bean
這種一般在自定義框架中比較常見,比如dubbo等
如果你採用SpringBoot爲基礎框架時,就比較好做。
- 拿到 ApplicationContext
@Resource
private ApplicationContext applicationContext;
- 通過ApplicationContext獲取 DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory =
(DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
- 創建 BeanDefinitionBuilder 用於定義構造函數,初始化、銷燬方法
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(YourBusinessService.class);
// 如果有構造函數參數
beanDefinitionBuilder.addConstructorArgValue(object1);
beanDefinitionBuilder.addConstructorArgValue(object2);
beanDefinitionBuilder.addConstructorArgValue(object3);
// 等等 有幾個構造函數的參數就設置幾個
// 設置 init方法
beanDefinitionBuilder.setInitMethodName("initMethodName");
// 設置 destory方法
beanDefinitionBuilder.setDestroyMethodName("destoryMethodName");
- 調用 DefaultListableBeanFactory 的 registerBeanDefinition 方法註冊成功
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
defaultListableBeanFactory.registerBeanDefinition("beanName", beanDefinitionBuilder.getBeanDefinition());
- 當然還有其他方式,比如 自定義 starter 等,這裏簡單列舉說明一下
例如:
自定義satarter resources -> META-INF -> spring.factories 文件中如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.middol.starter.mq.config.AliyunRocketMqAutoConfigure,\
com.middol.starter.mq.config.ApacheRocketMqAutoConfigure
這裏有兩個配置類 AliyunRocketMqAutoConfigure 和 ApacheRocketMqAutoConfigure
配置類大致情況如下:
@Configuration
@ConditionalOnClass({ONSFactory.class})
@ConditionalOnProperty(prefix = "middol.mq.aliyun.rocketmq", value = "enable", havingValue = "true")
@EnableConfigurationProperties({AliyunRocketMqProperties.class})
public class AliyunRocketMqAutoConfigure implements InitializingBean {
}
@Configuration
@ConditionalOnClass({SendMessageContext.class})
@ConditionalOnProperty(prefix = "middol.mq.apache.rocketmq", value = "enable", havingValue = "true")
@EnableConfigurationProperties({ApacheRocketMqProperties.class})
public class ApacheRocketMqAutoConfigure implements InitializingBean {
}
在配置類裏面的 @Bean方法new出的對象都會進入spring容器中。