想要让自己写的一个普通类创建的对象扔到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容器中。