大致的框架是从网上找来的资源。但是遇到了两个问题:
运行代码后,MongoDB数据库没有收到改变。 想起了在yaml中配置的mongodb参数,那些参数,data的上一层是spring,如下: spring boot在加载这些数据时,会得到一个MongoProperties
。按住Ctrl,然后点在那些值上,然后点进去后,就出来了。 该类的属性如下: 所以Spring Boot的加载过程中,会产生这样一个bean,通过注入的方式,拿到该类,便可以拿到相应的mongo db配置。再通过一定的分析,将配置信息传给自定义的MongoTemplate。
其中使用@Deprecated方法。 这里换成了其中的没有@Deprecated的构造方法。
先给出可以忽略掉_class字段的配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Configuration public class SpringMongoConfig { @Autowired public MongoProperties mongoProperties; public @Bean MongoDbFactory mongoDbFactory () throws Exception { return new SimpleMongoDbFactory (mongoProperties.createMongoClient(null , null ), mongoProperties.getDatabase()); } public @Bean MongoTemplate mongoTemplate () throws Exception { MappingMongoConverter converter = new MappingMongoConverter (new DefaultDbRefResolver (mongoDbFactory()), new MongoMappingContext ()); converter.setTypeMapper(new DefaultMongoTypeMapper (null )); return new MongoTemplate (mongoDbFactory(), converter); } }
从源代码去分析这个过程 从save()开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public void save (Object objectToSave) { Assert.notNull(objectToSave, "Object to save must not be null!" ); save(objectToSave, determineEntityCollectionName(objectToSave)); } public void save (Object objectToSave, String collectionName) { Assert.notNull(objectToSave, "Object to save must not be null!" ); Assert.hasText(collectionName, "Collection name must not be null or empty!" ); MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(objectToSave.getClass()); if (mongoPersistentEntity == null || !mongoPersistentEntity.hasVersionProperty()) { doSave(collectionName, objectToSave, this .mongoConverter); return ; } doSaveVersioned(objectToSave, mongoPersistentEntity, collectionName); } protected <T> void doSave (String collectionName, T objectToSave, MongoWriter<T> writer) { maybeEmitEvent(new BeforeConvertEvent <T>(objectToSave, collectionName)); assertUpdateableIdIfNotSet(objectToSave); DBObject dbDoc = toDbObject(objectToSave, writer); maybeEmitEvent(new BeforeSaveEvent <T>(objectToSave, dbDoc, collectionName)); Object id = saveDBObject(collectionName, dbDoc, objectToSave.getClass()); populateIdIfNecessary(objectToSave, id); maybeEmitEvent(new AfterSaveEvent <T>(objectToSave, dbDoc, collectionName)); }
执行toDbObject(objectToSave, writer);
后,debug显示的数据如下: 所以继续toDbObject(objectToSave, writer);
里面走: 所以进入MappingMongoConverter
的write(final Object obj, final DBObject dbo)
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public void write (final Object obj, final DBObject dbo) { if (null == obj) { return ; } Class<?> entityType = obj.getClass(); boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, DBObject.class) != null ; TypeInformation<? extends Object > type = ClassTypeInformation.from(entityType); if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) { typeMapper.writeType(type, dbo); } Object target = obj instanceof LazyLoadingProxy ? ((LazyLoadingProxy) obj).getTarget() : obj; writeInternal(target, dbo, type); }
与typeMapper初始化相关的代码如下: 因此,打开DefaultMongoTypeMapper
,找到writeType
方法,但是发现并没有,所以从它的父类DefaultTypeMapper<DBObject>
中找。 再看accessor.writeTypeTo()。这里的accessor在该类初始化的构造器中就已经被初始化,所以我们可以从继承该类的子类DefaultMongoTypeMapper中找到该类的实现,这里的accessor就是DefaultMongoTypeMapper的一个静态内部类。 这个时候,再回想一下之前的修改,有一种豁然开朗的感觉,哈哈。