spring动态创建Bean的实现

在spring工程中,所有的bean都是由spring来管理的,我们通常会基于注解来实现Bean的单例。但是有的情况下,我们需要动态的来创建这个bean,还要注册到spring容器,让spring容器来管理。
例如,我们在使用阿里云的oss的时候,有的时候由于我们有多个Bucket所以需要创建多个oss的对象。这里我们可以基于BeanFactoryPostProcessor来实现这个功能。

 

@Data
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliYunOssProperties {
    private Boolean enabled;

    private Map<String, AliYunOssInstantProperties> instance;
}

 

@Data
public class AliYunOssInstantProperties {
    private String beanName;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String endpoint;
    private String urlPrefix;
}

 

@Configuration
@ConditionalOnProperty(prefix = "aliyun.oss", value = {"enabled"}, havingValue = "true")
@EnableConfigurationProperties(value = {
        AliYunOssProperties.class
})
public class AliYunOssConfiguration implements EnvironmentAware, BeanFactoryPostProcessor {

    private AliYunOssProperties ossProperties;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;

        ossProperties.getInstance().forEach((key, props) -> {
            OSS oss = new OSSClientBuilder().build(props.getEndpoint(), props.getAccessKeyId(), props.getAccessKeySecret());
            OssProperties ossProperties = new OssProperties();
            ossProperties.setBucketName(props.getBucketName());
            ossProperties.setUrlPrefix(props.getUrlPrefix());

            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClass(AliYunOSS.class);
            beanDefinition.setBeanClassName(AliYunOSS.class.getName());
            ConstructorArgumentValues argumentValues = new ConstructorArgumentValues();
            argumentValues.addIndexedArgumentValue(0, oss);
            argumentValues.addIndexedArgumentValue(1, ossProperties);
            beanDefinition.setConstructorArgumentValues(argumentValues);

            beanFactory.registerBeanDefinition(StringUtils.isNotBlank(props.getBeanName()) ? props.getBeanName() : key + "_aliyunOSS", beanDefinition);
        });
    }

    @Override
    public void setEnvironment(Environment environment) {
        ossProperties = Binder.get(environment).bind("aliyun.oss", AliYunOssProperties.class).get();
    }
}
spring

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读