Spring MVC学习随笔-控制器(Controller)开发详解:调用业务对象、父子工厂拆分(applicationContext.xml、dispatcher.xml)
第四章、SpringMVC控制器开发详解 二
4.1 核心要点
4.2 SpringMVC控制器调用业务对象【SSM整合】
4.2.1 核心思路分析
4.2.2 编码
-
dispatcher.xml
<!--设置注解扫描的路径--> <context:component-scan base-package="com.baizhi"/> <!--引入SpringMVC的核心功能--> <mvc:annotation-driven/> <!--整合跳转路径,解耦合--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> <!--连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/myschool?useSSL=false&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!-- 创建SqlSessionFactory SqlSessionFactoryBean--> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.baizhi.entity"/> <property name="mapperLocations"> <list> <value>classpath:com.baizhi.mapper/*Mapper.xml</value> </list> </property> </bean> <!--创建DAO对象 MapperScannerConfigure--> <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/> <property name="basePackage" value="com.baizhi.dao"/> </bean> <!-- 配置事务--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
-
DAO
// **POJO** public class User implements Serializable { private Integer id; private String name; private String password; // **建表** create table t_user( id integer primary key auto_increment; name varchar(12), password varchar(12) ); // **DAO** public interface UserDAO { void save(User user); } // **Mapper** <mapper namespace="com.baizhi.dao.UserDAO"> <insert id="save"> insert into admin(name,password) values(#{name},#{password}) </insert> </mapper>
-
Service
public interface UserService { void register(User user); } Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDAO userDAO; @Override public void register(User user) { userDAO.save(user); } }
-
Controller
@Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/register") public String register(User user) { userService.register(user); return "regOk"; } }
4.2.3 父子工厂(父子容器) 拆分
-
现有SSM开发中存在的问题
MVC层的对象(Controller,mvc:annotation-driven/,视图解析器)与非MVC层的(连接池 DAO Service 事务),都配置在dispatcher.xml中,最终交给DispatcherServlet创建的工厂来进行实例化,存在着耦合问题,后续一旦替换MVC的实现,代码会受到影响,不利于项目的维护
-
如何解决
将非MVC的配置放在applicationContext.xml(引入ContextLoaderListener工厂读取配置)
-
把目前单一的工厂进行父子工厂的拆分
-
子工厂(DispatcherServlet)读取dispatcher.xml
完成与SpringMVC相关对象的创建:视图解析器、自定义类型转换器、拦截器等
-
父工厂(ContextLoaderListener)读取applicationContext.xml
完成与非SpringMVC相关对象的创建:连接池、DAO、Service、事务、Redis、ES、MQ等
-
-
工厂(容器)在需要获取对象进行操作时,首先获取子容器所创建的对象,如果没有则继续获得父容器所创建的对象
-
-
编码
-
子工厂(子容器)
# dispatcher.xml # SpringMVC相关的配置 <!--设置注解扫描的路径--> <context:component-scan base-package="com.baizhi"/> <!--引入SpringMVC的核心功能--> <mvc:annotation-driven/> <!--整合跳转路径,解耦合--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> # web.xml子容器的配置 <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
父工厂(父容器)
# applicationContext.xml # Spring相关配置 <context:component-scan base-package="com.baizhi"/> <!--连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/myschool?useSSL=false&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!-- 创建SqlSessionFactory SqlSessionFactoryBean--> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.baizhi.entity"/> <property name="mapperLocations"> <list> <value>classpath:com.baizhi.mapper/*Mapper.xml</value> </list> </property> </bean> <!--创建DAO对象 MapperScannerConfigure--> <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/> <property name="basePackage" value="com.baizhi.dao"/> </bean> <!-- 配置事务--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/> # web.xml父容器的配置 <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
-
4.2.4 父子容器问题
-
问题
按照现有父子工厂(容器)的开发方式,Service层没有添加事务。
-
问题成因
获取的是子容器的UserService,而子容器中没有事务配置,所以获取不到事务。
-
解决方案
之所以在子容器没有实现事务,是因为包扫描的全部的包,将service的包也交给子容器管理。
子容器:只扫描控制器及与MVC相关的内容 <context:component-scan base-package="com.baizhi.controller"/> 父容器:不扫描控制器与MVC相关的内容 <context:component-scan base-package="com.baizhi"> <context:exclude-filter type="aspectj" expression="com.baizhi.controller"/> </context:component-scan> 注意:在SpingBoot中不会出现父子容器的问题。
4.3 SpringMVC控制器调用业务对象总结(SSM)
4.3.1 完整编码总结
-
web.xml
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <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> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
dispatcher.xml
<context:component-scan base-package="com.baizhi.controller"/> <mvc:annotation-driven/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean>
-
applicationContex.xml
<context:component-scan base-package="com.baizhi"> <context:exclude-filter type="aspectj" expression="com.baizhi.controller"/> </context:component-scan> <!--连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/myschool?useSSL=false&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!-- 创建SqlSessionFactory SqlSessionFactoryBean--> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.baizhi.entity"/> <property name="mapperLocations"> <list> <value>classpath:com.baizhi.mapper/*Mapper.xml</value> </list> </property> </bean> <!--创建DAO对象 MapperScannerConfigure--> <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/> <property name="basePackage" value="com.baizhi.dao"/> </bean> <!-- 配置事务--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
-
DAO
// **POJO** public class User implements Serializable { private Integer id; private String name; private String password; // **建表** create table t_user( id integer primary key auto_increment; name varchar(12), password varchar(12) ); // **DAO** public interface UserDAO { void save(User user); } // **Mapper** <mapper namespace="com.baizhi.dao.UserDAO"> <insert id="save"> insert into admin(name,password) values(#{name},#{password}) </insert> </mapper>
-
Service
public interface UserService { void register(User user); } Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDAO userDAO; @Override public void register(User user) { userDAO.save(user); } }
-
Controller
@Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/register") public String register(User user) { userService.register(user); return "regOk"; } }
作者:扬眉剑出鞘
出处: https://www.cnblogs.com/eyewink/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。