我试图将spring-cloud-starter-aws用于一个目的 - 这样我的ec2实例就可以使用逻辑名而不是物理名访问其elasticache节点。我的问题是我想在没有AWS的本地环境中运行这个二进制文件(不使用elasticache节点),但我无法禁用。我得到一个异常:连接到服务端点时发生IOException:http://169.254.169.254/latest/dynamic/instance-identity/document
。例外是:
Error creating bean with name 'org.springframework.cloud.aws.context.support.io.ResourceLoaderBeanPostProcessor#0':
Cannot resolve reference to bean 'amazonS3'.
我认为这是因为aws sdk正在调用我没有在本地环境中运行的实例端点。如何禁用此功能?
答案 0 :(得分:0)
spring-cloud-starter-aws使用spring-cloud-aws-autoconfigure,它提供以下AWS相关配置:
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration
org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration
org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
所有这些都是由EnableAutoConfiguration触发的。如果你可以在没有EnableAutoConfiguration的情况下生活,你的问题就解决了。但是,由于您使用的是spring-cloud-starter-aws,我不希望出现这种情况。
不幸的是,只有ContextInstanceDataAutoConfiguration和ContextInstanceDataAutoConfiguration使用@ConditionalOnAwsCloudEnvironment,其余配置无论环境如何都会启动。它们中的大多数只能使用类似于以下内容的条件(此示例来自ContextCredentialsAutoConfiguration):
@ConditionalOnClass(name = {"com.amazonaws.auth.AWSCredentialsProvider"})
要不启动此类配置,您需要从类路径中删除com.amazonaws.auth.AWSCredentialsProvider类。这可以通过maven配置文件或花式模块化来实现,但我认为它通常是次优解决方案,因为这种项目重组存在重大的副作用。
我认为最简单的解决方案是从项目依赖项中删除spring-cloud-aws-autoconfigure并编写自己的配置类版本。这是一个适用于我的ContextCredentialsAutoConfiguration版本:
import mu.KLogging
import org.springframework.beans.factory.support.BeanDefinitionRegistry
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
import org.springframework.cloud.aws.context.config.annotation.ContextDefaultConfigurationRegistrar
import org.springframework.cloud.aws.context.config.support.ContextConfigurationUtils
import org.springframework.context.EnvironmentAware
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar
import org.springframework.context.annotation.Profile
import org.springframework.core.env.Environment
import org.springframework.core.type.AnnotationMetadata
@Configuration
@Import(ContextDefaultConfigurationRegistrar::class, AwsContextCredentialsAutoConfiguration.Registrar::class)
@ConditionalOnClass(name = ["com.amazonaws.auth.AWSCredentialsProvider"])
@Profile("!it")
class AwsContextCredentialsAutoConfiguration {
class Registrar : ImportBeanDefinitionRegistrar, EnvironmentAware {
companion object: KLogging()
private var environment: Environment? = null
override fun setEnvironment(environment: Environment) {
this.environment = environment
}
override fun registerBeanDefinitions(importingClassMetadata: AnnotationMetadata, registry: BeanDefinitionRegistry) {
val useDefaultCredentialsChain = this.environment!!.getProperty("cloud.aws.credentials.useDefaultAwsCredentialsChain", Boolean::class.java, false)
if (useDefaultCredentialsChain) {
logger.debug("Using default AWS credentials provider")
ContextConfigurationUtils.registerDefaultAWSCredentialsProvider(registry)
} else {
logger.debug("Using custom credentials provider (based on environment properties)")
ContextConfigurationUtils.registerCredentialsProvider(
registry,
this.environment!!.getProperty("cloud.aws.credentials.accessKey"),
this.environment!!.getProperty("cloud.aws.credentials.secretKey"),
this.environment!!.getProperty("cloud.aws.credentials.instanceProfile", Boolean::class.java, true) as Boolean && !this.environment!!.containsProperty("cloud.aws.credentials.accessKey"),
this.environment!!.getProperty("cloud.aws.credentials.profileName", "default"),
this.environment!!.getProperty("cloud.aws.credentials.profilePath"))
}
}
}
}
请注意@Profile(“!it”)注释,它是为集成测试启用的配置文件。因此,在集成测试期间会忽略配置,但您可以将其替换为您用于本地上下文的配置文件。
答案 1 :(得分:0)
感谢@Martian的先前回答,应用程序已进行了修改
首先在应用程序类中禁用与AWS相关的自动配置bean
@SpringBootApplication(exclude = {
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration.class
})
然后使用适当的条件设置创建一个AWS专用的Spring引导配置
/**
* Only enable AWS related auto config when we run in AWS Cloud
*/
@ConditionalOnAwsCloudEnvironment
@Import({
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration.class
})
public class AwsConfig {
}