Spring

本文详细探讨了Spring的核心概念,包括IoC和AOP,以及如何使用注解实现依赖注入。进一步讲解了Spring与Mybatis的整合,涉及事务管理和声明式事务处理。最后,阐述了Spring MVC的体系结构和请求处理流程,重点解析了参数传递的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring核心概念

1.Spring IoC

​ 控制翻转(Inversion of Control,IoC),也称为依赖注入(Dependency Injection,DI),是面向对象编程中的一种设计理念,用来降低程序代码之间的耦合度

/**
*用户DAO实现类。实现对User类的持久化操作
*/
public class UserMapperImpl implements UserMapper {
    @Override
    public void save(User user) {
        System.out.println("保存用户信息到数据库");
    }
}

/**
*用户业务类,实现对User功能的业务管理
*/
public class UserServiceImpl implements UserService{
	//实例化业务类,实现对User功能的业务管理
	private UserDao dao = new UserDaoImpl();
	public void addNewUser(User user){
		//调用UserDao的方法保存用户信息
		dao.save(user);
	}
}

如何使用依赖注入

public interface Ink {
    public String getColor(int r, int g, int b);
}
public interface Paper {
    public static final String newline="\r\n";

    public void putInChar(char c);

    public String getContent();

}
public class Printer {
    private Ink ink=null;
    private Paper paper=null;

    public  void setInk(Ink ink){
        this.ink=ink;
    }

    public void setPaper(Paper paper){
        this.paper=paper;
    }

    public void print(String str){
        System.out.println("使用"+ink.getColor(255,200,0)+"颜色打印:\n");
        for (int i = 0; i <str.length() ; i++) {
            paper.putInChar(str.charAt(i));
        }
        System.out.println(paper.getContent());
    }
}

2.Spring AOP

​ 面向切面编程(Aspect Oriented Programming, AOP)是软件编程思想发展到一定阶段的产物,是面向对象编程(Object Oriented Programming, OOP)有益补充

2.1使用Spring AOP实现日志输出
public class UserServiceImpl implements UserService {
    private UserDao dao= UserDaoFactory.getInstance();

    @Override
    public void addNewUser(User user) {
        dao.sava(user);
    }

    @Override
    public void save(User user) {

    }


    public void setDao(UserDao dao) {
        this.dao = dao;
    }

    private UserDao dao1;
}
/**
*定义包含增方法JavaBean
*/
public class UserServiceLogger {
    private static final Logger logger= (Logger) Logger.getLogger(String.valueOf(UserServiceLogger.class));
    public void before(JoinPoint jp){
        logger.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法,方法入参:"+Arrays.toString(jp.getArgs()));
    }
    public void after(JoinPoint jp, Object result){
        logger.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法,方法返回值:"+result);
    }
}

Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
        <bean id="dao" class="mapper.DaoImpl.UserDaoImpl"></bean>
    <bean id="service" class="service.serviceimpl.UserServiceImpl">
       <property name="dao" ref="dao"></property>
    </bean>
   <bean id="theLogger" class="service.UserServiceLogger"></bean>

    <aop:config>
         <aop:pointcut id="pointcut"expression="execution(public void addNewUser(pojo.User)pojo.User"/>
        <aop:bofore method="bofore" pointcut-ref="pointcut"></aop:bofore>
         <aop:after-returning method="after-returning" pointcut-ref="pointcut" returning="result"></aop:after-returning>
     </aop:config>
</beans>

Ioc和AOP使用扩展

3.多种方式实现依赖注入

3.1 构造注入
/**
*用户业务类,实现对User功能的业务管理
*/
public class UserServiceImpl implements UserService{
    //声明接口类型的引用和具体实现类解耦合
    private UserDao dao;
    
    //无参构造
    public UserServiceImpl(){}
    
    //用于为dao属性赋值的构造方法
    public UserServiceImpl(UserDao dao){
        this.dao=dao;
    }
    
    public void addNewUser(User user){
        //调用用户DAO的方法保存用户信息
        dao.save(user);
    }
}

Spring配置文件中将DAO对象构造注入的方式赋值给业务类对象相关属性的关键代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!--定义UserDao对象,并指定id为UserDao-->
    <bean id="userDao" class="dao.impl.UserDaoImpl"/>
	<!--定义UserServiceImpl对象,并指定id为UserService-->
    <bean id="userService" class="service.impl.UserServiceImpl"/>
    <!--通过定义的单参数构造方法为UserService的dao属性赋值-->
    <constructor-arg>
        <!--引用id为userDao的对象为UserService的dao属性赋值-->
        <ref bean="userDao">
    </constructor-arg>
</beans>
3.2 使用p命名空间实现属性注入

语法:p:属性名=“属性值”

引用Bean的属性

语法:p:属性名-ref=“Bean的id”

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!--使用p命名空间注入属性值-->
    <bean id="user" class="entity.User" p:username="张三" p:age="23" p:email="zhangsan@xxx.com"/>
    <bean id="userDao" class="dao.impl.UserDaoImpl"/>
    <bean id="userService" class="service.impl.UserServiceImpl" p:dao-ref="userDao"/>
    
</beans>
3.3 注入不同数据类型
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<!--使用<value>子元素注入字符串,基本数据类型及包装类-->
    <bean id="user" class="entity.User">
    	<property name="username">
            <value>张三</value>
        </property>
        <property name="age">
            <value>23</value>
        </property>
    </bean>
    
    <!-- 使用<![CDATA[]]>标记处理XML特殊字符-->
    <bean id="product" class="entity.Product">
        <property name="productName">
            <value>高露洁牙膏</value>
        </property>
         <property name="brand">
            <value><![CDATA[P&G]]></value>
        </property>
    </bean>
    <!--把XML特殊字符替换为实体引用-->
        <bean id="product" class="entity.Product">
        <property name="productName">
            <value>高露洁牙膏</value>
        </property>
         <property name="brand">
            <value>P&amp;G</value>
        </property>
    </bean>
</beans>
3.4 异常抛出增强

public class ErrorLogger {
  private Logger logger = Logger.getLogger(ErrorLogger.class);

    @AfterThrowing(pointcut = "execution(* service.UserService.*(..))",throwing = "e")
    public void afterThrowing(JoinPoint jp,RuntimeException e){
        logger.error(jp.getSignature().getName()+" 方法发生异常 "+e);
    }
}
 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--声明增强方法所在的Bean-->
    <bean id="theLogger" class="aop.ErrorLogger"></bean>
	<!--配置切面-->
    <aop:config>
        <!--定义切入点-->
            <aop:pointcut id="pointtcut" expression="execution(* service.UserService.*(..))"/>
            <aop:aspect ref="theLogger">
                <aop:after-throwing method="afterThrowing" pointcut-ref="pointtcut" throwing="e"/>
            </aop:aspect>
        </aop:config>

</beans>
3.5 环绕增强
public class AroundLogger {
    private Logger logger = Logger.getLogger(AroundLogger.class);

    public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable{
        logger.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法入参:"+ Arrays.toString(jp.getArgs()));
        try {
            Object result=jp.proceed();
            logger.info(jp.getTarget()+"的"+jp.getSignature().getName()+"方法,方法返回值:"+result);
            return result;
        }catch (Throwable e){
            logger.error(jp.getSignature().getName()+"方法发生异常:"+e);
            throw e;
        }finally {
            logger.info(jp.getSignature().getName()+"方法结束执行。");
        }
    }
}

Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

	 <!--声明增强方法所在的Bean-->
    <bean id="theLogger" class="aop.ErrorLogger"></bean>
	<!--配置切面-->
    <aop:config>
        <!--定义切入点-->
            <aop:pointcut id="pointtcut" expression="execution(* service.UserService.*(..))"/>
            <aop:aspect ref="theLogger">
                <aop:after-throwing method="afterThrowing" pointcut-ref="pointtcut"/>
            </aop:aspect>
        </aop:config>
</beans>

4.使用注解实现IoC的配置

4.1 使用注解定义Bean
@Component("UserMapper")
public class UserMapperImpl implements UserMapper {
    @Override
    public void save(User user) {
        System.out.println("保存用户信息到数据库");
    }
}
  • @Repository:用于标注DAO类
  • @Service:用于标注业务类
  • @Controller:用于标注控制器类
4.2 使用注解实现Bean组件装配

​ Spring提供了@Autowired注解实现Bean的装配

@Service("UserService")
public class UserServiceImpl implements UserService {
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Autowired
    @Qualifier("userDao")
    private UserMapper userMapper;
    @Override
    public void addNewUser(User user) {

    }
4.3 使用注解标注切面
@Aspect
public class UserServiceLogger {
    private static final Logger log = Logger.getLogger(String.valueOf(ErrorLogger.class));
    @Pointcut("execution(* service.UserService.*(..))")
    public void pointcut(){}

    @Before("pointcut()")
    public void before(JoinPoint jp){
        log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法入参:"+ Arrays.toString(jp.getArgs()));
    }
    @AfterReturning(pointcut = "execution(* service.UserService.*(..))",returning = "returnValue")
    public void afterReturning(JoinPoint jp,Object returnValue){
        log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法返回值:"+returnValue);
    }
}

Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:schemaLocation="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:compoent-scan base-package="service,dao"/>
    <bean class="aop.UserServiceLogger"></bean>
    <aop:aspectj-autoproxy />
</beans>

Mybatis与Spring的整合

5.Spring整合Mybatis的准备工作

​ 1.在项目中加入Sring,Mybatis及整合相关的JAR文件

​ 2.建立开发目录结构,创建实体类

public class Classes implements Serializable {
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    private Integer id;

    public Classes() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;
}

3.创建数据访问接口

public interface ClassesMapper {
    List<Classes> selectList();

}

4.配置SQL映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.ClassesMapper">
    <resultMap id="classesMap" type="pojo.Classes">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
    </resultMap>
    <select id="selectList" resultMap="classesMap">
        select id,name from classes
    </select>
</mapper>

5.Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">

        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url">
            <!-- 千万注意,这里不能换行 -->
            <value><![CDATA[jdbc:mysql://127.0.0.1:3306/easybuy?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8]]></value>
        </property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <!--单个单个类的扫描 -->
    <bean id="classesMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="mapper.OrderMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
    <!-- 扫描整个包下的所有:命名规则就是首字母改成小写 -->
    <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper" />
    </bean>
    <bean id="classesBiz" class="biz.impl.OrderBizImpl">
        <property name="orderMapper" ref="classesMapper"></property>
    </bean>
    <bean id="classesAction" class="action.OrderAction">
        <property name="orderBiz" ref="classesBiz"></property>
    </bean>
</beans>

测试类

public class TestClasses {
    @Test
    public  void testRole(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ClassesAction classesAction = (ClassesAction) context.getBean("classesAction");
        List<Classes> classesList = classesAction.selectList();
        for (Classes classes:classesList){
            System.out.println(classes.getId()+","+classes.getName());
        }
    }
}

6.为业务层添加声明式事务

  • DEFAULT:默认值,表示使用数据库默认的事务隔离级别
  • READ_UNCOMMITTED:未提交读
  • READ_COMMITTED:提交读
  • REPEATABLE_READ:可重复读
  • SERIALIZABLE:串行读

7.使用注解实现声明式事务处理

​ @Transactional注解也可以设置事务属性的值,默认的@Transactional设置如下

  • 事务传播设置是 PROPAGATION_REQUIRED
  • 事务隔离级别是 ISOLATION_DEFAULT
  • 事务是读/写
  • 事务超时默认是依赖于事务系统的,或者事务超时没有被支持
  • 任何RuntimeExeption 将触发事务回滚,但是任何checked Execption将不触发事务回滚

​ @Transactional注解的属性

属性类型说明
propagation枚举型:Propagation该属性用于设置事务的传播行为,具体取值可参考表6-7。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
isolation枚举型:Isolation该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置
readOnly布尔型该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)
timeoutint型(以秒为单位)该属性用于设置事务的超时秒数,默认值为-1表示永不超时
rollbackFor一组Class类的实例,必须是Throwable的子类该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)
rollbackForClassName一组Class类的实例,必须是Throwable的子类该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称:@Transactional(rollbackForClassName=“RuntimeException”)
noRollbackFor一组Class类的名称,必须是Throwable的子类该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)
noRollbackForClassName一组Class类的名称,必须是Throwable的子类该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=“RuntimeException”)

Spring配置补充

8.使用JNDI数据源

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <Context>
    	<Resouce name="jdbc/smbms" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdel="30" maxWait="10000" username="root" password="root" diverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&amp;characterEncoding=utf-8"/>
    </Context>
    
    <!--通过JNDI配置DataSource-->
    <bean id="datasource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <!--通过jndiName指定引用的JNDI数据源名称-->
        <property name="jndiName">
            <value>java:comp/env/jdbc/smbms</value>
        </property>
    </bean>
</beans>

9.理解Bean的作用域

作用域说明
singleton使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。
prototype使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
request该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。
session该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。
global-session该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

10.Spring的自动装配

​ autowire属性值及其说明

autowire属性值说明
no即不启用自动装配。Autowire默认的值。
byType通过属性的类型查找JavaBean依赖的对象并为其注入。比如类Computer有个属性printer,类型为Printer,那么,指定其autowire属性为byType后,Spring
IoC容器会查找Class属性为Printer的bean,使用Seter方法为其注入。
byName通过属性的名字的方式查找JavaBean依赖的对象并为其注入。比如说类Computer有个属性printer,指定其autowire属性为byName后,Spring
IoC容器会在配置文件中查找id/name属性为printer的bean,然后使用Seter方法为其注入。
autodetect在byType和constructor之间自动的选择注入方式。

Spring MVC 体系结构和处理请求控制器

11.MVC设置模式

  • 数据访问接口:DAO层
  • 处理业务逻辑:Service层
  • 数据实体:POJO
  • 负责前端请求的接受并处理:Servlet
  • 负责前端页面展示:JSP
11.1 JSP Model1

​ 主要还是通过JSP页面和业务逻辑处理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bELrkQEm-1570243664708)(C:\Users\lw\Desktop\20160626172053254.jpg)]

11.2 JSP Model2

​ 把业务流程控制交给控制器来实现,JSP专注于视图的展示即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KtktyZVn-1570243664709)(C:\Users\lw\Desktop\20160626172036334.jpg)]

12.Spring MVC环境搭建

  • 引入jar文件
  • Spring MVC配置
  • 创建Controller(处理请求的控制器)
  • 创建View
  • 部署运行

13.Spring MVC框架的请求处理流程及体系结构

13.1 Spring MVC框架的请求处理流程
  • 实现用户发送请求到前端控制器,前端控制器根据请求信息,来决定来选择哪个页面控制器来运行处理,并把请求委托给它,即Servlet控制器的控制逻辑部分
  • 页面控制器接受到请求后,进行业务处理,处理完毕后返回一个ModelAndView
  • 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的真正视图,并把模型数据传入以便将视图渲染展示
  • 前端控制器再次收回控制权,将响应结果返回给用户
13.2 Spring MVC框架的体系结构
  • ​ 客户端发出HTTP请求,Web应用服务器接收此请求。如匹配DispatcherServlet的请求映射路径,则Web容器将该请求转交给DispatcherServlet处理;
  • DispatcherServlet拿到请求之后,根据请求的信息(URL、请求参数、HTTP方法等)及HandlerMapping的配置找到处理请求的处理器(Handler);
  • 当DispatcherServlet找到相应的Handler之后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter可以理解为真正使用Handler来干活的人。
  • 在请求信息真正到达调用Handler的处理方法之前的这段时间,Spring MVC还完成了很多工作,它会将请求信息以一定的方式转换并绑定到请求方法的入参,对于入参的对象会进行数据转换、数据格式化以及数据校验等。这些都做完以后,最后才真正调用Handler的处理方法进行相应的业务逻辑处理。
  • 处理器完成业务处理之后,将一个ModelAndView对象返回给DispatcherServlet,其中包含了逻辑视图名和模型数据信息。
  • 处理器完成业务处理之后,将一个ModelAndView对象返回给DispatcherServlet,其中包含了逻辑视图名和模型数据信息。
  • 得到真正的视图对象之后,DispatcherServlet会根据ModelAndView对象中的模型数据对View进行视图渲染。
  • 最终客户端获得响应消息。
13.2.1 Spring MVC 框架的特点
  • 清晰的角色划分,Spring MVC在Model,View和Controller方面提供了一个非常清晰的角色划分,这三个方面真正是各司其职,各负其责
  • 灵活的配置功能
  • 提供了大量的控制器接口和实现类,开发者可以使用Spring提供的控制权实现类,也可以自己实现控制器接口
  • 真正做到与View层的实现无关
  • 国际化支持
  • 面向接口编程
  • Spring提供了Web应用开发的一整套流程,不仅仅是MVC,它们之间可以很方便地结合一起

14.参数传递(View to Controller)

​ 1.@RequestMapping

@RequestMapping(value = "/welcome",method = RequestMethod.GET,params = "username")
    public String welcome(@RequestParam String username){
        logger.info("welcome:"+username);
        return "indxe";
   }

2.@RequestParam

  • value:参数名
  • required:是否必需,默认为true,表示请求中必须包含对应的参数名,若不存在将抛出异常
  • defaultValue;默认参数名,不推荐使用

15.参数传递(Controller to View)

1.ModelAndView

​ (1)添加模型数据

  • ModelAndView addObject(String attributeName,Object attriteValue):该方法的第一个参数为key值,第二个参数为key对应的value
  • ModelAndView addAllObjects(Map<String,?>modelMap):从此方法中可以看出,模型数据也是一个Map对象,我们可以添加Map对象到Model中

​ (2)设置视图

  • void setView(View view):指定一个具体的视图对象
  • void setViewName(String viewName):指定一个逻辑视图名

2.Model

​ 除了可以使用ModelView对象来返回模型数据外,我们还可以使用Spring MVC 提供的Model对象来完成模型数据的传递

3.Map

   @RequestMapping("/index3")
    public String index3(String username, Map<String,Object> model){
        logger.info("hello,SpringMVC! username:"+username);
        model.put("username",username);
        return "index";
    }
默认参数名,不推荐使用

### 15.参数传递(Controller to View)

   1.ModelAndView

​		(1)添加模型数据

- ModelAndView addObject(String attributeName,Object attriteValue):该方法的第一个参数为key值,第二个参数为key对应的value
- ModelAndView addAllObjects(Map<String,?>modelMap):从此方法中可以看出,模型数据也是一个Map对象,我们可以添加Map对象到Model中

​       (2)设置视图

- void setView(View view):指定一个具体的视图对象
- void setViewName(String viewName):指定一个逻辑视图名

 2.Model

​            除了可以使用ModelView对象来返回模型数据外,我们还可以使用Spring MVC 提供的Model对象来完成模型数据的传递

 3.Map

```java
   @RequestMapping("/index3")
    public String index3(String username, Map<String,Object> model){
        logger.info("hello,SpringMVC! username:"+username);
        model.put("username",username);
        return "index";
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值