[置顶] maven搭建SpringMVC+Spring+hibernate+JPA
2016-03-27 23:39
567 查看
maven搭建SpringMVC+Spring+hibernate+JPA
JPA Java Persistence API,JPA吸收了很多ORM框架的持久化思想,是在ORM框架的基础上,抽象出来的一层规范。使用JPA你可以随时更换底层支持JPA的ORM框架,而不需要与ORM绑死,同时Spring对JPA的支持,使得JPA写出的代码很精简。环境搭建
maven 依赖配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.jdk>1.6</project.build.jdk> <spring.version>3.2.2.RELEASE</spring.version> <spring.data.jpa.version>1.4.3.RELEASE</spring.data.jpa.version> <junit.version>4.11</junit.version> <fastjson.version>1.2.7</fastjson.version> <commonslang3.verison>3.1</commonslang3.verison> <common.io.version>2.4</common.io.version> <common.dbcp.version>1.4</common.dbcp.version> <common.file.version>1.3</common.file.version> <servlet.api.version>3.0.1</servlet.api.version> <servlet.jsp.version>2.2</servlet.jsp.version> <hibernate.jpa.version>1.0.1.Final</hibernate.jpa.version> <hibernate.core.version>3.5.5-Final</hibernate.core.version> <hibernate.validator.version>4.3.1.Final</hibernate.validator.version> <mysql.version>5.1.6</mysql.version> <quartz.version>1.8.6</quartz.version> <logback.version>1.1.2</logback.version> <java.mail.version>1.4.5</java.mail.version> <asm.version>3.3.1</asm.version> </properties> <dependencies> <!-- asm begin --> <dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>${asm.version}</version> </dependency> <!-- asm end --> <!-- mail begin --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>${java.mail.version}</version> </dependency> <!-- mail end --> <!-- logback begin --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!-- logback end --> <!-- database begin --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>${common.dbcp.version}</version> </dependency> <!-- database end --> <!-- common begin --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commonslang3.verison}</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${common.io.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${common.file.version}</version> </dependency> <!-- common end --> <!-- SPRING BEGIN --> <!-- 引用此类会自动加载spring的core(其它组件要都要使用到这个包里的类,是其它组件的基本核心,外部依赖Commons Logging)、beans(包含访问配置文件、创建和管理bean 以及进行DI AOP 操作相关的所有类)、aop(提供AOP(面向切面编程)的实现 )、context包(为Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- 提供对事务的支持 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <!-- 包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- 对JUNIT等测试框架的简单封装 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- 这个jar 文件包含Spring MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何类。 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- 这个jar是spring扩展 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- spring 对jpa的支持 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>${spring.data.jpa.version}</version> </dependency> <!-- SPRING END --> <!-- hibernate start --> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.0-api</artifactId> <version>${hibernate.jpa.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.core.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.core.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> </dependency> <!-- hibernate end --> <!-- fastJson start --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!-- fastjson end --> <!-- quartz start --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>${quartz.version}</version> </dependency> <!-- quartz end --> <!-- junit start --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- junit end --> <!--servlet start --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.api.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>${servlet.jsp.version}</version> <scope>provided</scope> </dependency> <!--servlet end --> </dependencies>
WEB配置文件
<!-- spring的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 加载配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/applicationContext.xml classpath*:/applicationContext-poj.xml </param-value> </context-param> <!-- 解决字符串乱码问题 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- sping mvc 配置 所有.do的请求都经过spingmvc的servlet --> <servlet> <servlet-name>springServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
spring的applicationContext配置文件
<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 --> <context:component-scan base-package="com"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- 将配置统一提取到properties中管理 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:application.properties</value> </list> </property> </bean> <!-- 数据源配置, 使用DBCP数据库连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- Connection Pooling Info --> <property name="maxActive" value="${dbcp.maxActive}" /> <property name="maxIdle" value="${dbcp.maxIdle}" /> <property name="defaultAutoCommit" value="false" /> <!-- 连接Idle一个小时后超时 --> <property name="timeBetweenEvictionRunsMillis" value="3600000" /> <property name="minEvictableIdleTimeMillis" value="3600000" /> </bean> <!--指定实现JPA的适配器--> <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" /> </bean> <!-- JPA实体管理工厂的配置 --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/> <property name="packagesToScan" value="com"/><!--待扫描的实体类包,不再需要persistence.xml了--> <property name="jpaProperties"> <props> <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <!-- Jpa 事务配置 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- Spring Data Jpa配置 --> <jpa:repositories base-package="com.durd" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/> <!-- 使用annotation定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <!-- JSR303 Validator定义 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
spring mvc配置文件
<!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="com" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- <mvc:annotation-driven/> --> <!-- 将无法mapping到Controller的path交给default servlet handler处理 --> <!-- <mvc:default-servlet-handler/> --> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> <!-- 定义JSP文件的位置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>
问题总结
parent里是dependencies还是dependencyManagement
之前看到很多项目把dependency都定义在了dependencyManagement中,这样有一个好处就是我再dependencyManagement中定义的依赖并不会被项目module加载,如果module需要加载这些依赖,只需要在module中dependencies中声明下groupId跟artifactId即可,不需要再声明version。但在我们的项目中依赖的jar包比较单一,没有使用dependencyManagement而是直接使用的dependencies,这样管理jar包比较统一,否则还需要两个地方维护jar包。项目里jar包依赖版本冲突
在引用jar的过程中,开始只是定义了一些基础的jar包。但是一保存pom发现很多依赖的jar都被引入近来了,这里很多框架都是依赖很多相同的基础包,有些会存在jar包冲突问题,但是maven的依赖的传递性,并不会帮我们自动解决这些版本冲突问题,只会遵守maven的传递性规则(第一原则:路径最近者优先(A->B->C->D(1.0),A->E->D(2.0)那么A的依赖应该是D2.0而不是D1.0)第二原则:路径相等时,第一声明者优先。)所以这里需要我们自己去解决这些问题。建议先声明基础jar包,在去声明框架级jar包,这样对项目的基础jar包就有比较清晰的了解。同时借助maven提供的依赖分析命令可以很容易的解决这些问题。
profiles配置没有编译到.properties配置文件中
刚开始也是自己大意了,在application.xml中使用了很都${username}标识符把配置项都提到了application.properties配置文件中。<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:application.properties</value> </list> </property> </bean>
在application.properties中也使用了替换符号,所有的配置文件都弄到了maven提供的profiles中。
<profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <filters> <filter>profiles/dev.properties</filter> </filters> </build> </profile> <profile> <id>test</id> <build> <filters> <filter>profiles/test.properties</filter> </filters> </build> </profile> <profile> <id>online</id> <build> <filters> <filter>profiles/pro.properties</filter> </filters> </build> </profile> </profiles>
但是在编译中发现application.properties中的配置没有被dev.properties替换,原因是maven编译时没有指定配置文件的目录,并开始filter。
<build> <finalName>web</finalName> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.properties</include> <include>**/*.conf</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>**/*.ftl</include> <include>**/*.sql</include> <include>**/*.xml</include> </includes> </resource> </resources> </build>
启动报错
class path resource [com/mchange/v2/c3p0/QueryConnectionTester.class] cannot be opened because it does not exist
这个问题太奇怪了,我在项目里用的连接池是dbcp但是不知道为什么会需要引用c3p0的jar包,排查了一下,发现
spring data jpa配置时
<jpa:repositories base-package="com" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
com的级别太大了,可能引入了其他的类,导致提示c3p0的类找不到错误。
需要注意的一点,自动扫描
一般spring的配置文件跟springMVC的配置文件都会分开配置,扫描时,会利用include-filter跟exclude-filter进行控制,一般spring配置文件会配置成<!-- 使用annotation 自动扫描bean, 并保证@Required、@Autowired的属性被注入 --> <context:component-scan base-package="com.xxx"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
而springMVC则配置为
<!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="com.xxx.xxx" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
如何2个扫描器有重合的类,可能会引起问题是事务不起作用,解决的方法是添加use-default-filters=”false”
相关文章推荐
- java 选择器
- HDU 1002 A + B Problem II(大数加法,C,Java两个版本)
- java中的"goto"--label
- JAVA中的File.separate(跨平台路径)
- 抽象类与接口
- 《Java程序设计》第4周学习总结
- 20145321 《Java程序设计》第4周学习总结
- Java中函数参数的传递是值传递还是引用传递
- 20145310 《Java程序设计》第4周学习总结
- JAVA设计模式之单利模式
- 20145216史婧瑶《Java 程序设计》第4周学习总结
- 20145216史婧瑶《Java 程序设计》第4周学习总结
- Java过滤器与SpringMVC拦截器之间的关系与区别
- java 表单验证
- spring 源码解析
- spring简介
- spring aop 原理
- JavaSript模块规范 - AMD规范与CMD规范介绍
- Junit单元测试的简单使用(主要是在spring框架下的项目)
- java是面向未来的!