【问题标题】:Exclude config classes from spring context从 spring 上下文中排除配置类
【发布时间】:2022-01-12 07:28:57
【问题描述】:

我有一个配置 Cassandra 数据库的类:

@Configuration
@EnableCassandraRepositories(basePackages = { BASE_PACKAGE })
public class CassandraConfig {

    @Value("${spring.data.cassandra.contact-points}")
    private String contactPoints;
    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspaceName;
    @Value("${spring.data.cassandra.datacenter-name}")
    private String datacenterName;
    @Value("${spring.data.cassandra.port}")
    private int port;

    @Bean
    public CqlSessionFactoryBean session() {
        CqlSessionFactoryBean session = new CqlSessionFactoryBean();
        session.setContactPoints(contactPoints);
        session.setKeyspaceName(keyspaceName);
        session.setLocalDatacenter(datacenterName);
        session.setPort(port);
        return session;
    }
...

}

我有一个只加载弹簧上下文的空测试

@SpringBootTest
class ApplicationTest {

    @Test
    void contextLoads() {
    }

}

当我运行它时,我看到了这个异常消息:

Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext

...

Caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node(endPoint=127.0.0.1/<unresolved>:9042, hostId=null, hashCode=29caef8c): [com.datastax.oss.driver.api.core.connection.ConnectionInitException: [s0|control|connecting...] Protocol initialization request, step 1 (OPTIONS): failed to send request (io.netty.channel.StacklessClosedChannelException)]
    at app//com.datastax.oss.driver.api.core.AllNodesFailedException.copy(AllNodesFailedException.java:141)
    at app//com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149)
    at app//com.datastax.oss.driver.api.core.session.SessionBuilder.build(SessionBuilder.java:835)
    at app//org.springframework.data.cassandra.config.CqlSessionFactoryBean.buildSystemSession(CqlSessionFactoryBean.java:498)
    at app//org.springframework.data.cassandra.config.CqlSessionFactoryBean.afterPropertiesSet(CqlSessionFactoryBean.java:451)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 166 more
    Suppressed: com.datastax.oss.driver.api.core.connection.ConnectionInitException: [s0|control|connecting...] Protocol initialization request, step 1 (OPTIONS): failed to send request (io.netty.channel.StacklessClosedChannelException)
        at app//com.datastax.oss.driver.internal.core.channel.ProtocolInitHandler$InitRequest.fail(ProtocolInitHandler.java:356)
        at app//com.datastax.oss.driver.internal.core.channel.ChannelHandlerRequest.writeListener(ChannelHandlerRequest.java:87)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
        at app//io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:184)
        at app//io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:95)
        at app//io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:30)
        at app//com.datastax.oss.driver.internal.core.channel.ChannelHandlerRequest.send(ChannelHandlerRequest.java:76)
        at app//com.datastax.oss.driver.internal.core.channel.ProtocolInitHandler$InitRequest.send(ProtocolInitHandler.java:193)
        at app//com.datastax.oss.driver.internal.core.channel.ProtocolInitHandler.onRealConnect(ProtocolInitHandler.java:124)
        at app//com.datastax.oss.driver.internal.core.channel.ConnectInitHandler.lambda$connect$0(ConnectInitHandler.java:57)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:571)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:550)
        at app//io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
        at app//io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616)
        at app//io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:609)
        at app//io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
        at app//io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:321)
        at app//io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:337)
        at app//io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:707)
        at app//io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
        at app//io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
        at app//io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
        at app//io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
        at app//io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at app//io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base@17.0.1/java.lang.Thread.run(Thread.java:833)
        Suppressed: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /127.0.0.1:9042
        Caused by: java.net.ConnectException: Connection refused
            at java.base/sun.nio.ch.Net.pollConnect(Native Method)
            at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
            at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)
            at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:330)
            at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334)
            at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:707)
            at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
            at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
            at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
            at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
            at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
            at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
            at java.base/java.lang.Thread.run(Thread.java:833)
    Caused by: io.netty.channel.StacklessClosedChannelException
        at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0()(Unknown Source)

据我了解,它尝试连接到数据库,但无法连接,因此失败。 我尝试了不同的方法来从上下文加载中排除这个类,比如@EnableAutoConfiguration(exclude = CassandraConfig.class),但是它失败了

java.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes: com.myproject.test.config.CassandraConfig

是否有一些建议或最佳实践来解决这个问题?

【问题讨论】:

    标签: java spring cassandra


    【解决方案1】:

    您遇到的错误是有道理的,CassandraConfig 不是自动配置,而是配置类。

    要排除它,您可以使用 Spring 配置文件:

    @Configuration
    @Profile("!test")
    public class CassandraConfig {
    

    然后在你的测试类中:

    @SpringBootTest(properties = "spring.profiles.active=test")
    class ApplicationTest {
    

    【讨论】:

    • 一般来说,它可以工作,但我也有依赖于这个配置的控制器、服务和存储库层。所以,他们失败了
    • 也许您应该提供更详细的描述。这回答了你的问题......
    猜你喜欢
    • 2017-02-05
    • 2013-01-18
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多