MongoDB中的"_class"字段是由Spring Data MongoDB自动添加的,用于存储每个文档所属的Java类的全限定名。这个字段的存在是为了在查询时能够准确地将文档映射回Java对象。

但在某些情况下,我们可能不希望自动添加"_class"字段。例如,当我们使用MongoDB作为纯粹的文档存储时,不需要将文档映射回Java对象,或者当我们希望减少存储空间和网络传输时。

下面是一种方法可以在Spring Data MongoDB中禁用自动添加"_class"字段。

首先,我们需要定义一个自定义的MappingMongoConverter并覆盖其getMappingContext()方法。MappingMongoConverter是Spring Data MongoDB中负责对象与文档之间的转换的类。

public class CustomMappingMongoConverter extends MappingMongoConverter {
    public CustomMappingMongoConverter(MongoDbFactory mongoDbFactory, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
        super(mongoDbFactory, mappingContext);
    }

    @Override
    protected void writeInternal(Object obj, Document dbo, MongoPersistentEntity<?> entity) {
        super.writeInternal(obj, dbo, entity);
        dbo.remove("_class");
    }

    @Override
    protected void writeInternal(Object obj, Bson bson) {
        super.writeInternal(obj, bson);
        ((BsonDocument) bson).remove("_class");
    }
}

上面的代码中,我们通过覆盖writeInternal()方法,在将Java对象转换为文档或Bson时删除"_class"字段。

接下来,我们需要修改MongoConfiguration类,让它返回我们自定义的MappingMongoConverter。

@Configuration
public class MongoConfiguration extends AbstractMongoConfiguration {

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

    @Override
    public MongoClient mongoClient() {
        return MongoClients.create("mongodb://localhost:27017");
    }

    @Override
    public MongoCustomConversions customConversions() {
        return new MongoCustomConversions(Collections.emptyList());
    }

    @Override
    public MappingMongoConverter mappingMongoConverter() throws Exception {
        MappingMongoConverter converter = new CustomMappingMongoConverter(mongoDbFactory(),
                mappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return converter;
    }
}

在上面的配置类中,我们返回了自定义的MappingMongoConverter,并且将默认的TypeMapper设置为null,这样就完全禁用了"_class"字段的自动添加。

最后,我们可以编写一个简单的应用程序来测试是否成功禁用了"_class"字段。

@Repository
public class MyRepository {
    @Autowired
    private MongoTemplate mongoTemplate;

    public void saveDocument(Document document) {
        mongoTemplate.save(document);
    }

    public Document findDocumentById(String id) {
        return mongoTemplate.findById(id, Document.class);
    }
}

@Service
public class MyService {
    @Autowired
    private MyRepository myRepository;

    public void saveDocument(Document document) {
        myRepository.saveDocument(document);
    }

    public Document findDocumentById(String id) {
        return myRepository.findDocumentById(id);
    }
}

@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

在上面的代码中,我们定义了一个MyRepository和MyService类,用于保存和查找MongoDB中的文档。注意到这里的Document类没有任何与"_class"字段相关的注解。

然后,我们可以编写一个测试类来验证自动添加"_class"字段是否成功禁用。

@SpringBootTest
@RunWith(SpringRunner.class)
public class MyServiceTest {
    @Autowired
    private MyService myService;

    @Test
    public void testSaveAndFindDocument() {
        Document document = new Document("name", "John Doe");
        myService.saveDocument(document);

        Document savedDocument = myService.findDocumentById(document.getId());
        System.out.println(savedDocument.toJson());
    }
}

在上面的测试方法中,我们保存了一个简单的文档,并从数据库中检索出该文档。如果成功禁用了"_class"字段,输出的文档应该不包含"_class"字段。

通过运行上述测试,我们可以确认"_class"字段已成功禁用。

综上所述,我们可以通过自定义MappingMongoConverter并覆盖writeInternal()方法,以及修改MongoConfiguration类来禁用Spring Data MongoDB自动添加的"_class"字段。这样可以在某些情况下减少存储空间和网络传输。