简体   繁体   中英

Why isn't my spring boot (mongo) bean being created / used?

I'm trying to use SpringBoot to talk to a Mongo database.

It is working using spring-boot-starter-data-mongodb and auto configuring a default bean which does allow my MongoRepository classes to talk to the DB ok.

However, I want to override the defaults. I could use application.properties but I need to be able to pass the connection parameters as options on the command line as the application starts up.

I've tried changing the port to break it, I've added debug to the Mongo config and it seems whatever I do the default spring config is being used regardless. It's as if the @Configuration annotation is ignored.

I've tried various flavours of configuring the main application class (specifying conf location, adding @Configuration to main class, with and without @SpringBootApplication ...), but here is where I am at the moment....

package somepackage

@EnableAutoConfiguration
@ComponentScan
public class MyApplication {

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
    ....
}



package somepackage.conf; // should be picked up by ComponentScan, no?
@Configuration
public class MongoConf {

    @Bean
    public MongoClientFactoryBean mongo() throws Exception {
        MongoClientFactoryBean mongo = new MongoClientFactoryBean();

        /*
         setting to silly values to try to prove it is trying to create connections using this bean - expected to see errors because can't create connection... */
        mongo.setHost("flibble");
        mongo.setPort(345);
        return mongo;
    }
}

You should actually use built in Spring Boot MongoDb Starter features and related auto configuration through application properties. Custom host, port, passwords etc. can and should be set via dedicated Spring Boot MongoDB Properties :

spring.data.mongodb.authentication-database= # Authentication database name.
spring.data.mongodb.database=test # Database name.
spring.data.mongodb.field-naming-strategy= # Fully qualified name of the FieldNamingStrategy to use.
spring.data.mongodb.grid-fs-database= # GridFS database name.
spring.data.mongodb.host=localhost # Mongo server host.
spring.data.mongodb.password= # Login password of the mongo server.
spring.data.mongodb.port=27017 # Mongo server port.
spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories.
spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. When set, host and port are ignored.
spring.data.mongodb.username= # Login user of the mongo server.

And link to the full list of supported properties is here .

In addition to RafalG's suggestion about MongoProperties, I combined that with the ApplicationArguments class and now I'm getting somewhere....

@Bean
@Primary
public MongoProperties mongoProperties(ApplicationArguments args) {
    MongoProperties props = new MongoProperties();
    String[] mongoHostAndPort = args.getSourceArgs()[3].split(":");
    props.setHost(mongoHostAndPort[0]);
    props.setPort(Integer.parseInt(mongoHostAndPort[1]));
    return props;
}

@Bean
public MongoClientFactoryBean mongo() {
    return new MongoClientFactoryBean();
}

Of course there's lots of error handling to add (nulls, non-ints etc) but hopefully if may help someone else.

@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
@Profile("!testing")
public class TestMongoConfig extends AbstractMongoConfiguration {

private static final MongodStarter starter =     MongodStarter.getDefaultInstance();

private MongodExecutable _mongodExe;
private MongodProcess _mongod;
private MongoClient _mongo;

@Value("${spring.data.mongodb.host}")
private String host;

@Value("${spring.data.mongodb.port}")
private Integer port;

@Override
protected String getDatabaseName() {
    return "test";
}


@Bean
public Mongo mongo() throws Exception {
    _mongodExe = starter.prepare(new MongodConfigBuilder()
                        .version(Version.Main.PRODUCTION)
                        .net(new Net(port, Network.localhostIsIPv6()))
                        .build());
    _mongod = _mongodExe.start(); 
    return  new MongoClient(host, port);
}

@Override
public String getMappingBasePackage() {
    return "com.test.domain";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM