diff --git a/spring-data-commons-core/pom.xml b/spring-data-commons-core/pom.xml
index a2a1a2d18..cfc37809b 100644
--- a/spring-data-commons-core/pom.xml
+++ b/spring-data-commons-core/pom.xml
@@ -16,6 +16,7 @@
2.5.01.01.1.3
+ 1.9.7
@@ -32,6 +33,18 @@
${org.springframework.version}true
+
+ org.springframework
+ spring-oxm
+ ${org.springframework.version}
+ true
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ ${jackson.version}
+ true
+ org.springframeworkspring-web
diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/RepositoryNameSpaceHandler.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/RepositoryNameSpaceHandler.java
new file mode 100644
index 000000000..7c314088d
--- /dev/null
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/RepositoryNameSpaceHandler.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.repository.config;
+
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.NamespaceHandler;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+/**
+ * {@link NamespaceHandler} to register {@link BeanDefinitionParser}s for repository initializers.
+ *
+ * @author Oliver Gierke
+ * @since 1.4
+ */
+public class RepositoryNameSpaceHandler extends NamespaceHandlerSupport {
+
+ private static final BeanDefinitionParser PARSER = new ResourceReaderRepositoryPopulatorBeanDefinitionParser();
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.xml.NamespaceHandler#init()
+ */
+ public void init() {
+ registerBeanDefinitionParser("unmarshaller-populator", PARSER);
+ registerBeanDefinitionParser("jackson-populator", PARSER);
+ }
+}
diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParser.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParser.java
new file mode 100644
index 000000000..598790c1b
--- /dev/null
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/config/ResourceReaderRepositoryPopulatorBeanDefinitionParser.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.repository.config;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.data.repository.init.JacksonRepositoryPopulatorFactoryBean;
+import org.springframework.data.repository.init.UnmarshallerRepositoryPopulatorFactoryBean;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * {@link BeanDefinitionParser} to parse repository initializers.
+ *
+ * @author Oliver Gierke
+ */
+public class ResourceReaderRepositoryPopulatorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClassName(org.w3c.dom.Element)
+ */
+ @Override
+ protected String getBeanClassName(Element element) {
+
+ String name = element.getLocalName();
+ return "unmarshaller-populator".equals(name) ? UnmarshallerRepositoryPopulatorFactoryBean.class.getName()
+ : JacksonRepositoryPopulatorFactoryBean.class.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
+ */
+ @Override
+ protected void doParse(Element element, BeanDefinitionBuilder builder) {
+
+ String localName = element.getLocalName();
+
+ builder.addPropertyValue("resources", element.getAttribute("locations"));
+
+ if ("unmarshaller-populator".equals(localName)) {
+ parseXmlPopulator(element, builder);
+ } else if ("jackson-populator".equals(localName)) {
+ parseJsonPopulator(element, builder);
+ }
+ }
+
+ /**
+ * Populates the {@link BeanDefinitionBuilder} for a Jackson reader.
+ *
+ * @param element
+ * @param builder
+ */
+ private void parseJsonPopulator(Element element, BeanDefinitionBuilder builder) {
+
+ String objectMapperRef = element.getAttribute("object-mapper-ref");
+
+ if (StringUtils.hasText(objectMapperRef)) {
+ builder.addPropertyReference("mapper", objectMapperRef);
+ }
+ }
+
+ /**
+ * Populate the {@link BeanDefinitionBuilder} for XML reader.
+ *
+ * @param element
+ * @param builder
+ */
+ private void parseXmlPopulator(Element element, BeanDefinitionBuilder builder) {
+
+ String unmarshallerRefName = element.getAttribute("unmarshaller-ref");
+
+ if (StringUtils.hasText(unmarshallerRefName)) {
+ builder.addPropertyReference("unmarshaller", unmarshallerRefName);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateIdAsFallback()
+ */
+ @Override
+ protected boolean shouldGenerateIdAsFallback() {
+ return true;
+ }
+}
diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java
new file mode 100644
index 000000000..0276019cf
--- /dev/null
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/AbstractRepositoryPopulatorFactoryBean.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.repository.init;
+
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.io.Resource;
+import org.springframework.data.repository.support.Repositories;
+
+/**
+ * {@link FactoryBean} to set up a {@link ResourceReaderRepositoryPopulator} with a {@link JacksonResourceReader}.
+ *
+ * @author Oliver Gierke
+ */
+public abstract class AbstractRepositoryPopulatorFactoryBean extends
+ AbstractFactoryBean implements ApplicationListener {
+
+ private Resource[] resources;
+ private RepositoryPopulator populator;
+
+ /**
+ * Configures the {@link Resource}s to be used to load objects from and initialize the repositories eventually.
+ *
+ * @param resources the resources to set
+ */
+ public void setResources(Resource[] resources) {
+ this.resources = resources;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType()
+ */
+ @Override
+ public Class> getObjectType() {
+ return ResourceReaderRepositoryPopulator.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
+ */
+ @Override
+ protected ResourceReaderRepositoryPopulator createInstance() throws Exception {
+
+ ResourceReaderRepositoryPopulator initializer = new ResourceReaderRepositoryPopulator(getResourceReader());
+ initializer.setResources(resources);
+
+ this.populator = initializer;
+
+ return initializer;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
+ */
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+
+ if (event.equals(getBeanFactory())) {
+ Repositories repositories = new Repositories(event.getApplicationContext());
+ populator.populate(repositories);
+ }
+ }
+
+ protected abstract ResourceReader getResourceReader();
+}
diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonRepositoryPopulatorFactoryBean.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonRepositoryPopulatorFactoryBean.java
new file mode 100644
index 000000000..bebd231f0
--- /dev/null
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonRepositoryPopulatorFactoryBean.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.repository.init;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ * {@link FactoryBean} to set up a {@link ResourceReaderRepositoryPopulator} with a {@link JacksonResourceReader}.
+ *
+ * @author Oliver Gierke
+ */
+public class JacksonRepositoryPopulatorFactoryBean extends AbstractRepositoryPopulatorFactoryBean {
+
+ private ObjectMapper mapper;
+
+ /**
+ * Configures the {@link ObjectMapper} to be used.
+ *
+ * @param mapper
+ */
+ public void setMapper(ObjectMapper mapper) {
+ this.mapper = mapper;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.repository.init.AbstractRepositoryPopulatorFactoryBean#getResourceReader()
+ */
+ @Override
+ protected ResourceReader getResourceReader() {
+ return new JacksonResourceReader(mapper);
+ }
+}
diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonResourceReader.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonResourceReader.java
new file mode 100644
index 000000000..98adfdb3d
--- /dev/null
+++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/init/JacksonResourceReader.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.repository.init;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.DeserializationConfig.Feature;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.core.io.Resource;
+import org.springframework.util.ClassUtils;
+
+/**
+ * A {@link ResourceReader} using Jackson to read JSON into objects.
+ *
+ * @author Oliver Gierke
+ */
+public class JacksonResourceReader implements ResourceReader {
+
+ private static final String DEFAULT_TYPE_KEY = "_class";
+ private static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper();
+
+ static {
+ DEFAULT_MAPPER.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+ private final ObjectMapper mapper;
+ private String typeKey = DEFAULT_TYPE_KEY;
+
+ /**
+ * Creates a new {@link JacksonResourceReader}.
+ */
+ public JacksonResourceReader() {
+ this(DEFAULT_MAPPER);
+ }
+
+ /**
+ * Creates a new {@link JacksonResourceReader} using the given {@link ObjectMapper}.
+ *
+ * @param mapper
+ */
+ public JacksonResourceReader(ObjectMapper mapper) {
+ this.mapper = mapper == null ? DEFAULT_MAPPER : mapper;
+ }
+
+ /**
+ * Configures the JSON document's key to lookup the type to instantiate the object. Defaults to
+ * {@value JacksonResourceReader#DEFAULT_TYPE_KEY}.
+ *
+ * @param typeKey
+ */
+ public void setTypeKey(String typeKey) {
+ this.typeKey = typeKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.repository.init.ResourceReader#readFrom(org.springframework.core.io.Resource, java.lang.ClassLoader)
+ */
+ public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception {
+
+ InputStream stream = resource.getInputStream();
+ JsonNode node = mapper.reader(JsonNode.class).readTree(stream);
+
+ if (node.isArray()) {
+
+ Iterator elements = node.getElements();
+ List