Eclipse,Tomcat,Maven,Spring MVC,Mongo(和疯狂)

Tim*_*ter 5 java eclipse spring mongodb maven

我一直在尝试使用Maven,Spring MVC和Mongo在Tomcat(由Eclipse发起)下运行的完全简单的Eclipse项目.我已经阅读了几篇文章并尝试了我发现的教程,然而,有些东西总是引起异常而且练习也化为乌有.我花了很长时间来讨论我的选择并尝试将这个项目放在一起,我最近的尝试是从Eclipse内部创建一个maven-archtype-webapp.

在我创建项目之后,我将其设置为在Tomcat 7下运行.然后我修改我的pom文件以添加Spring MVC和Mongo DB功能:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>springTest</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>springTest Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <spring.version>3.2.3.RELEASE</spring.version>
        <jdk.version>1.6</jdk.version>
        <spring-mongo.version>1.2.2.RELEASE</spring-mongo.version>
    </properties>    
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>${spring-mongo.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>springTest</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <url>http://localhost:8080/manager/text</url>
                    <server>my-tomcat</server>
                    <path>/SampleSpringMaven</path>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Run Code Online (Sandbox Code Playgroud)

就代码而言,应用程序只有3个类:springTest.model.Person,springTest.service.PersonService和springTest.controller.PersonController.这是每个的代码:package springTest.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class Person { 
    @Id
    private String id;
    private String name;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

package springTest.service;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import springTest.model.Person;

@Repository
public class PersonService {
@Autowired
protected MongoTemplate mongoTemplate;

public static final String COLLECTION_NAME = "person";

public void addPerson(Person person) {
    if (!mongoTemplate.collectionExists(Person.class)) {
        mongoTemplate.createCollection(Person.class);
    }
        person.setId(UUID.randomUUID().toString());
        mongoTemplate.insert(person, COLLECTION_NAME);
    }
    public List<Person> listPerson() {
        return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
    }
    public void deletePerson(Person person) {
        mongoTemplate.remove(person, COLLECTION_NAME);
    }
    public void updatePerson(Person person) {
        mongoTemplate.insert(person, COLLECTION_NAME);
    }
}

package springTest.service;

import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import springTest.model.Person;

@Repository
public class PersonService {
    @Autowired
    protected MongoTemplate mongoTemplate;

    public static final String COLLECTION_NAME = "person";

    public void addPerson(Person person) {
        if (!mongoTemplate.collectionExists(Person.class)) {
            mongoTemplate.createCollection(Person.class);
        }
        person.setId(UUID.randomUUID().toString());
        mongoTemplate.insert(person, COLLECTION_NAME);
    }

    public List<Person> listPerson() {
        return mongoTemplate.findAll(Person.class, COLLECTION_NAME);
    }

    public void deletePerson(Person person) {
        mongoTemplate.remove(person, COLLECTION_NAME);
    }

    public void updatePerson(Person person) {
        mongoTemplate.insert(person, COLLECTION_NAME);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,这是我启动应用程序时遇到的异常:

Mar 6, 2014 8:57:52 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:springTest' did not find a matching property.
Mar 6, 2014 8:57:52 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Mar 6, 2014 8:57:52 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Mar 6, 2014 8:57:52 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 484 ms
Mar 6, 2014 8:57:52 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Mar 6, 2014 8:57:52 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.42
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Mar 6, 2014 8:57:54 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Mar 6, 2014 8:57:55 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected org.springframework.data.mongodb.core.MongoTemplate springTest.service.PersonService.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: tried to access method org.springframework.core.GenericTypeResolver.getTypeVariableMap(Ljava/lang/Class;)Ljava/util/Map; from class org.springframework.data.util.ClassTypeInformation
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:695)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected org.springframework.data.mongodb.core.MongoTemplate springTest.service.PersonService.mongoTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: tried to access method org.springframework.core.GenericTypeResolver.getTypeVariableMap(Ljava/lang/Class;)Ljava/util/Map; from class org.springframework.data.util.ClassTypeInformation
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 23 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: tried to access method org.springframework.core.GenericTypeResolver.getTypeVariableMap(Ljava/lang/Class;)Ljava/util/Map; from class org.springframework.data.util.ClassTypeInformation
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 25 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: tried to access method org.springframework.core.GenericTypeResolver.getTypeVariableMap(Ljava/lang/Class;)Ljava/util/Map; from class org.springframework.data.util.ClassTypeInformation
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
    ... 37 more
Caused by: java.lang.IllegalAccessError: tried to access method org.springframework.core.GenericTypeResolver.getTypeVariableMap(Ljava/lang/Class;)Ljava/util/Map; from class org.springframework.data.util.ClassTypeInformation
    at org.springframework.data.util.ClassTypeInformation.<init>(ClassTypeInformation.java:96)
    at org.springframework.data.util.ClassTypeInformation.<clinit>(ClassTypeInformation.java:42)
    at org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper.<clinit>(DefaultMongoTypeMapper.java:45)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.<init>(MappingMongoConverter.java:107)
    at org.springframework.data.mongodb.core.MongoTemplate.getDefaultMongoConverter(MongoTemplate.java:1687)
    at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:189)
    at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:175)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
    ... 39 more
Mar 6, 2014 8:57:55 AM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Mar 6, 2014 8:57:55 AM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/springTest] startup failed due to previous errors
Mar 6, 2014 8:57:55 AM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Mar 6, 2014 8:57:55 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Mar 6, 2014 8:57:55 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Mar 6, 2014 8:57:55 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2131 ms
Run Code Online (Sandbox Code Playgroud)

我遗漏了xml文件,对不起:web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
              http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <display-name>Sample Spring Maven Project</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>  
Run Code Online (Sandbox Code Playgroud)

MVC-调度-servlet.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="
    http://www.springframework.org/schema/data/mongo
    http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- Scans the classpath of Components to auto-detect -->
    <context:component-scan use-default-filters="false" base-package="springTest">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>

    <mongo:mongo host="127.0.0.1" port="27017" write-concern="JOURNAL_SAFE">
        <mongo:options connections-per-host="50"
                   threads-allowed-to-block-for-connection-multiplier="4"
                   connect-timeout="1000"
                   max-wait-time="1500"
                   auto-connect-retry="true"
                   socket-keep-alive="true"
                   socket-timeout="1500"
                   slave-ok="true"
                   write-number="1"
                   write-timeout="0"
                   write-fsync="false"/>
    </mongo:mongo>

    <mongo:db-factory mongo-ref="mongo" dbname="test" username="admin" password="password" />

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>

    <bean id="personController" class="springTest.controller.PersonController" />
    <bean id="personService" class="springTest.service.PersonService" />
    <bean id="person" class="springTest.model.Person" />

    <!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
</bean>
</beans>  
Run Code Online (Sandbox Code Playgroud)

我真的需要理解为什么这样做会失败(对MongoTemplate对象中的方法使用IllegalAccessError).我的依赖项版本号是否会搞砸了?我只是无法弄清楚发生了什么.

问候,

蒂姆

小智 1

我可以看到你的数据库工厂引用是“mongo”。但是在 mongoTemplate bean 中,您已将数据库工厂的引用指定为 mongoDbFactory。这可能就是无法创建 mongoTemplate bean 的原因。