用SPRingMVC+Spring+Mybati这三个框架用了这么长的时间了,虽然说会用,但是有种知其然不知其所以然的感觉,工作之余特地自己搭建了一个,对里面的各种配置了解得深入了一点,现总结如下,会穿插一点lz个人对其中的理解,有误之处还望轻碰后指出,如果对后来人有所帮助,lz会非常开心,因为lz开始学的时候就是参考了非常多前辈写的博客才有今天的。 1楼主用的是Myeclipse,创建一个java web 项目:需要说明的是,next到最后不要忘了点击Generate web.xml deployment descriptor,会在WEB-INF中自动生成web.xml文件,不用在别的位置拷贝。 2,web.xml
<!-- Spring 配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <!-- 此处自定义配置文件位置,需加contextConfigLocation --> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <!-- ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。 --> <!-- 如果在web.xml中不写任何参数配置信息,默认的路径是/WEB-INF/applicationContext.xml, 在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml; --> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>说明1:classpath。 需要说明的是很多初学者(包括楼主)对这个classpath不知指的是哪个路径 classpath:首先 classpath是指 WEB-INF文件夹下的classes目录 ,可能有的人就会懵逼,在环境中哪里WEB-INF 哪里有classes,在计算机中找到你创建的项目进入到WEB-INF中就会发现有一个classes文件夹 如下:
附:在web.xml中classpath和classpath*的区别 classpath 和 classpath* 区别: classpath:只会到你指定的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 如果我在web.xml中定义的是:classpath:META-INF/spring/application-context.xml 那么只有META-INF/spring底下的application-context.xml会被加载到上下文中。 “**/” 表示的是任意目录; “*/applicationContext-.xml” 表示任意目录下的以”applicationContext-“开头的XML文件。 程序部署到tomcat后,src目录下的配置文件会和class文件一样,自动copy到应用的 WEB-INF/classes目录下 classpath:与classpath*:的区别在于, 前者只会从第一个classpath中加载,而 后者会从所有的classpath中加载 如果要加载的资源, 不在当前ClassLoader的路径里,那么用classpath:前缀是找不到的, 这种情况下就需要使用classpath*:前缀 ,在多个classpath中存在同名资源,都需要加载, 那么用classpath:只会加载第一个,这种情况下也需要classpath*:前缀 注意: 用classpath*:需要遍历所有的classpath,所以加载速度是很慢的,因此,在规划的时候,应该尽可能规划好资源文件所在的路径,尽量避免使用classpath*。 参考:https://zhidao.baidu.com/question/919326352548812699.html,http://perfy315.iteye.com/blog/2009258 classpath:applicationContext.xml读取的是web.xml同级目录下classes中的Spring配置文件applicationContext.xml 说明一点,注意导入的包不要少添加了,或者class的包名加类不要写错了,写完用ctrl+鼠标左键 检查一下如果能跳转到包下就说明没问,如果点不动则说明包没导入或包名加类写的有问题。 说明2:contextConfigLocation ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。加载applicationContext.xml文件,如果在web.xml中不写任何参数配置信息,默认的路径是/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml; 如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/applicationContext-*.xml </param-value> </context-param>由此可见applicationContext.xml的文件位置就可以有两种默认实现: 第一种:直接将之放到/WEB-INF下,之在web.xml中声明一个listener; 第二种:将之放到classpath下,但是此时要在web.xml中加入,用它来指明你的applicationContext.xml的位置以供web容器来加载。 参考:http://blog.csdn.net/ysughw/article/details/8992322
<!-- SpringMVC 配置文件 --> <servlet> <!-- DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller来处理。 --> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 与加载applicationContent类似 --> <param-value>classpath:mvc.xml</param-value> </init-param> <!-- 表示启动容器时初始化该Servlet; --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 表示哪些请求交给Spring Web MVC处理 --> <url-pattern>*.do</url-pattern> </servlet-mapping>说明1: DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下: 1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析; 2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器); 3、 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器); 4、通过ViewResolver解析逻辑视图名到具体视图实现; 5、本地化解析; 6、渲染具体的视图等; 7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。 8、 如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求(如我们上面配置的“/”),就会造成js文件、CSS文件、图片文件等静态资源无法访问。 9、处理静态页面,JS,CSS文件, 第一种是采用,(一般Web应用服务器默认的Servlet名称是”default”,所以这里我们激活Tomcat的defaultServlet来处理静态文件,在web.xml里配置如下代码即可:)
<!-- 该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问 http://localhost/foo.css ,现在http://localhost/static/foo.css --> <!-- 不拦截静态文件 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/js/*</url-pattern> <url-pattern>/css/*</url-pattern> <url-pattern>/images/*</url-pattern> <url-pattern>/fonts/*</url-pattern> </servlet-mapping>第二种是采用,在springmvc的配置文件中加入以下代码:
<mvc:resources mapping="/js/**" location="/static_resources/Javascript/"/> <mvc:resources mapping="/styles/**" location="/static_resources/css/"/> <mvc:resources mapping="/images/**" location="/static_resources/images/"/>说明2: load-on-startup:表示启动容器时初始化该Servlet; url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“*.html”表示拦截所有以html为扩展名的请求。 参考:http://blog.csdn.net/lqx1988221/article/details/12620689 web.xml就写这么多。 3:applicationContext.xml
<!-- 读取属性配置文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:db.properties"></property> </bean>读取的配置文件在src目录下,如图:
db.properties为:
driver=com.MySQL.jdbc.Driverurl=jdbc:mysql://localhost:3306/testusername=rootpassWord=123456<!-- 配置date source --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </bean>读取配置文件中键值对通过¥{}来赋值
<!-- 配置工厂 --> <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- SqlSessionFactory 有一个单独的必须属性,就是 JDBC 的 DataSource。这可以是任意 的 DataSource--> <property name="dataSource" ref="dataSource"/> <!-- 一个通用的属性是 configLocation,它是用来指定 MyBatis 的 XML 配置文件路径的。 --> <property name="configLocation" value="classpath:mybatis.cfg.xml"/> </bean><!-- 声明式事务 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="get" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* cn.sxt.service.impl.*.*(..))" id="pointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/> </aop:config> <context:component-scan base-package="cn.sxt"/>用法
@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。 虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。 默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。参考:http://blog.csdn.net/bao19901210/article/details/41724355
4mvc.xml
<!-- 扫描该包下的注解 --> <context:component-scan base-package="cn.sxt.controller"/>5mybatis.cfg.xml<mappers> <!-- 所有mapper文件填写位置 --> <mapper resource="cn/sxt/vo/user.mapper.xml" /> </mappers>6user.mapper.xml<mapper namespace="cn.sxt.vo.user.mapper"> <select id="list" resultType="cn.sxt.vo.User"> select * from user </select></mapper>7UserDaoImpl
/*@Repository用于标注数据访问组件,即DAO组件*/@Repository("userDao")public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{ @Autowired @Override public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { super.setSqlSessionFactory(sqlSessionFactory); } @Override public List<User> list() { // TODO Auto-generated method stub return getSqlSession().selectList("cn.sxt.vo.user.mapper.list"); }}8UserServiceImpl
@Service("userService")public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; public void setUserDao(UserDao userDao){ this.userDao=userDao; } public List<User> list(){ return userDao.list(); }}@Controllerpublic class UserController { @Autowired private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } @RequestMapping("/list") public String list(ModelMap map){ map.addAttribute("list",userService.list()); return "/list.jsp"; }}@Service用于标注业务层组件 @Controller用于标注控制层组件(如struts中的action @Repository用于标注数据访问组件,即DAO组件 @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 附demo源码:http://download.csdn.net/detail/btwangzhi/9752783
新闻热点
疑难解答