• Spring | SpringMVC


    1)        Spring是一个IOC(DI)和AOP容器框架。

    1)        Spring的优良特性

       依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。

       面向切面编程:Aspect Oriented Programming——AOP

       一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方     类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

     IOC(Inversion of Control):反转控制

    应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取所需要的资源;

    反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可

    DI(Dependency Injection):依赖注入

    IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。

    IOC 描述的是一种思想,而DI 是对IOC思想的具体实现. 

    Bean配置解释

             <bean>: 让IOC容器管理一个具体的对象.

                                id:  唯一标识

                                class: 类的全类名. 通过反射的方式创建对象.

                                            Class cls = Class.forName("com.atguigu.spring.helloWorld.Person");

                                            Object obj  = cls.newInstance(); 无参数构造器

                                <property>: 给对象的属性赋值.

                                         name: 指定属性名 ,要去对应类中的set方法.

                                         value:指定属性值   

    获取Bean的方式

    1) 从IOC容器中获取bean时,除了通过id值获取,还可以通过bean的类型获取。但如果同一个类型的bean在XML文件中配置了多个,则获取时会抛出异常,所以同一个类型的bean在容器中必须是唯一的。

    //1.创建IOC容器
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
            //2.获取HelloWorld对象;唯一标示的id为“Hi”
            HelloWorld bean = (HelloWorld) ioc.getBean("Hi");
    或者这种方式来获取Bean:
        HelloWorld helloWorld = ioc.getBean(HelloWorld. class);    
    或者可以使用另外一个重载的方法,同时指定bean的id值和类型
    HelloWorld helloWorld = cxt.getBean(“helloWorld”,HelloWorld. class);        
            //3.调用HelloWorld中的方法
            bean.sayHello();

     给bean的属性赋值(普通类型的值、引用类型的值)

        <!-- 给bean的属性赋值,(普通类型的值、引用类型的值)
        1.通过vlaue属性或vlaue子标签(了解)    2.通过ref属性或ref子标签(了解)
            -->
        <bean id="employee" class="com.atguigu.spring.entities.Employee">
            <property name="id" value="1"></property>
            
            <property name="lastName">
                <value>kk</value>    可使用<value>子标签来赋值;
            </property>
            
            <property name="email" value="kk@qq.com"> </property>
            <property name="salary" value="10000"> </property>
            <!-- <property name="deptId" value="2"> </property> -->
            <property name="dept" ref="department"></property>  有引用数据类型的值 
            
        </bean>
            配置Department,再将配置好的Department注入到Employee中(使用ref<bean id="department" class="com.atguigu.spring.entities.Department">
            <property name="id" value="2"></property>
            <property name="name" value="设计"></property>
        </bean>
    
    

    引用外部属性文件 <!-- 方式一:直接配置数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root"></property> <property name="password" value="123456"></property> <property name="url" value="jdbc:mysql://localhost:3306/test"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> </bean> <!-- 方式二: 引入外部属性文件以properties的格式 --> <context:property-placeholder location="classpath:druid.properties"/> <!-- 通过引入外部配置文件引入数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> <property name="url" value="${jdbc.url}"></property> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="initialSize" value="${jdbc.initialSize}"></property> <property name="minIdle" value="${jdbc.minIdle}"></property> <property name="maxActive" value="${jdbc.maxActive}"></property> <property name="maxWait" value="${jdbc.maxWait}"></property> </bean>

    创建properties属性文件(位于src/main/resources);

    在xml中引入context名称空间;

    指定properties属性文件的位置;从properties属性文件中引入属性值

    <!-- 指定properties属性文件的位置 -->
    <!-- classpath:xxx 表示属性文件位于类路径下 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    基于注解配置Bean

    1)  手动装配:以value或ref的方式明确指定属性值都是手动装配。

    2)  自动装配:根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。

    相对于XML方式而言,通过注解的方式配置bean更加简洁和优雅,而且和MVC组件化开发的理念十分契合,是开发中常用的使用方式。

    1) 普通组件:@Component

            标识一个受Spring IOC容器管理的组件

    2) 持久化层组件:@Repository

    标识一个受Spring IOC容器管理的持久化层组件

    3) 业务逻辑层组件:@Service

      标识一个受Spring IOC容器管理的业务逻辑层组件

    4) 表述层控制器组件:@Controller

    标识一个受Spring IOC容器管理的表述层控制器组件

    5) 组件命名规则

             ①默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id

             ②使用组件注解的value属性指定bean的id

             注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以                       @Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。

    Spring Web MVC (SpringMVC)

    Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口

    C(controler ,处理用户请求的,与servlet功能是一样的,请求先到达C层;)

    M(model模型控制器(业务模型和数据模型))

    V(View视图,视图解析器来渲染视图)

    请求到达C之后要去拿Model,它再返回给C数据,C再找View(数据以什么方式进行呈现给用户),V处理完之后把页面给C,最后它给用户。

    表现层(出来用户请求的)、业务逻辑层(出来业务逻辑的)、持久化层(DAO连接数据库)。

    SpringMVC在这个基础上又加了一个前端控制器(配置在web.xml中);它负责分配,让哪个C去处理请求;

    请求先到前端控制器它先拦截,由它来分配。

     )  在web.xml中配置DispatcherServlet(前端控制器)

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
    
        <!-- 配置前端控制器|核心控制器 DispatcherServlet -->
        <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>  文件位置,服务器解析xml时来造这个对象,
            </init-param>
            <load-on-startup>1</load-on-startup> 服务器一启动就把对象造好了,不用发请求
        </servlet>
    
        <!-- Map all requests to the DispatcherServlet for handling -->
        <servlet-mapping>
            <servlet-name>springDispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>  /是为了覆盖tomcat服务器中的xml,为了替代default它拦截的请求(/它是除了jsp不拦截其他都拦截后交给它处理);
        </servlet-mapping>            //替换它,替换它拦截的请求交给我处理;  jsp有专门的jsp处理
    
        <!-- 通过过滤方式配置中文,后端显示中文不会乱码 -->
        <filter>
            <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
    </web-app>
    <?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:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
        <!-- 设置自动扫描的包 -->
        <context:component-scan base-package="com.atguigu.springmvc"></context:component-scan>
    
        <!-- 配置视图解析器来渲染视图 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
            <!-- 配置前缀 -->
            <property name="prefix" value="/WEB-INF/views/"></property> 
            <!-- 配置后缀 -->
            <property name="suffix" value=".jsp"></property>
        </bean>
        
        <!-- 处理静态资源,如加载juqery等 -->
        <mvc:default-servlet-handler/>
        <!-- 配置了处理静态资源之后,Handler中的@RequestMapping注解就失效了,此时必须配置以下标签 -->
        <mvc:annotation-driven></mvc:annotation-driven>
        
    </beans>

    前缀 + 返回值 + 后缀,拼接起来 /WEB-INF/views/success.jsp

    创建处理器(让当前类成为处理器,加@Controller注解)

    index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    
    <script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery-1.7.2.js"></script>
    <script type="text/javascript">
        /* alert($); */
    </script>
    </head>
    <body>
        <a href="${pageContext.request.contextPath }/hello">Hello SpringMVC</a>
        <br>
        <a href="${pageContext.request.contextPath }/testValue">testValue</a>
        <br>
        <a href="${pageContext.request.contextPath }/testMethod">testMethod</a>
        
        <form action="${pageContext.request.contextPath}/testMethod" method="post">
            <input type="submit" value="提交">
        </form>
        
        <a href="${pageContext.request.contextPath}/testRequestParam?username=admin">test RequestParam</a>
        
        
        <h2>测试入参POJO</h2>
        <form action="${pageContext.request.contextPath }/testPOJO">
            员工编号:<input type="text" name="id"><br>
            员工姓名:<input type="text" name="lastName"><br>
            员工邮箱:<input type="text" name="email"><br>
            员工薪水:<input type="text" name="salary"><br>
            部门编号:<input type="text" name="dept.id"><br>
            部门名字:<input type="text" name="dept.name"><br>
                    <input type="submit" value="TestPOJO提交">
        </form>
        
        <h3>测试入参为原生SevletAPI</h3>
        <form action="${pageContext.request.contextPath}/testServletAPI" method="post">
            员工姓名:<input type="text" name="username">
                <input type="submit" value="TesetServletAPI">
        </form>
        
        
        <!-- 转发 -->
        <a href="${pageContext.request.contextPath }/testModelAndView">ModelView</a><br>
        <a href="${pageContext.request.contextPath }/testMap">Map</a><br>
        <!-- 重定向 -->
        <a href="${pageContext.request.contextPath }/testRedirect">Redirect</a>
    </body>
    </html>
    @Controller
    public class SpringMVCHandler {
    
    public static final String SUCCESS = "success";
    /*    @RequestMapping处理请求映射;注解中的属性 
     *   1.value -用来设置要映射的请求地址
          -该属性的类型是一个String类型的数组,如果映射的请求地址(必须携带请求参数params)只有一个那么大括号可以省略, 而且value属性名也可以省略不写 
         2.method
          -用来设置要映射的请求方式 -如果没有指定改属性如post,那么只看处理的请求地址,不管请求方式,不是默认出来get请求*/
        //测试value
        @RequestMapping(value={"/testValue", "testValue2"})
        public String testValue() {
            System.out.println("测试value");
            return SUCCESS;
        }
        //测试method
        @RequestMapping(value="/testMethod" ) 可加请求参数params={"username=admin", "age=18"}
        public String testMethod() {
            System.out.println("测试method");
            return SUCCESS;
            
            /*点击超链接是get请求*/
        }
        //测试post请求
        @RequestMapping(value= "/testMethod", method=RequestMethod.POST)
        public String testPost() {
            System.out.println("测试post");
            return SUCCESS;
        }
        
    /*    @RequestParam注解 -用来映射请求参数,如果Handler方法的入参的参数名和请求参数的参数名一致,那么该注解可以不写(不建议这样)
           value属性: -用来设置请求参数的参数名 required属性: -用来设置该请求参数是否是必须的,默认是true,是必须的
           defaultValue属性: -用来设置一个默认值,如果没有携带该请求参数那么将使用此默认值*/
        @RequestMapping("/testRequestParam")
        public String testRequestParam(@RequestParam("username") String username, 
                                     @RequestParam(value="age", required=false, defaultValue="0") int age) { //或者Integer
            
            System.out.println("用户名是:" + username);
            System.out.println("年龄是:" + age);
            return SUCCESS;
            
        }
        
        //Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配, 自动为该对象填充属性值,支持级联属性
        @RequestMapping("/testPOJO")
        public String testPOJO(Employee employee) {
            
            System.out.println("员工信息为:" + employee);
            
            return SUCCESS;
            
        }
        
        /*SpringMVC 的 Handler 方法可以接受以下ServletAPI 类型的参数 1) ★HttpServletRequest 2)* ★HttpServletResponse 
                                        3) ★HttpSession
    */ @RequestMapping("/testServletAPI") public String testSevletAPI(HttpServletRequest request, HttpServletResponse response) { String username = request.getParameter("username"); System.out.println("用户名是:" + username); return SUCCESS; } //处理响应数据方法一:将Handler的方法的返回值设置为ModelAndView @RequestMapping("/testModelAndView") public ModelAndView testModelAndView() { //①创建对象 ModelAndView mv = new ModelAndView(); Employee employee = new Employee(2, "嘿嘿", "hei@qq.com", 20000.3, null); //②添加数据模型 mv.addObject("emp", employee); //③设置视图名 mv.setViewName("success"); return mv; } //处理响应数据二: /*方法的返回值还是String类型,在Handler的方法入参中传入Map、Model或ModelMap      不管在Handler的方法中传入Map、Model还是ModelMap,SpringMVC都会转换为一个ModelAndView对象*/ @RequestMapping("/testMap") public String testMap(Map<String, Object> map) { Employee employee = new Employee(1, "smile", "sl@126.com", 20000.01, null); map.put("emp", employee); //将模型数据放到map中,最终会放到request域中 return SUCCESS; } //重定向 @RequestMapping("/testRedirect") public String testRedict() { System.out.println("开始重定向"); return "redirect:/redirect.jsp"; } }
    Spring与SpringMVC需不需要整合?
         *     不整合
         *         1.将所有的配置都配置到SpringMVC的配置文件中
         *         2.将Spring的配置文件通过import标签引入到SpringMVC的配置文件中
         *     ★整合
         *         Spring的配置文件中管理Service、Dao、数据源、事务以及与其他框架的整合
         *         SpringMVC的配置文件管理Handler、视图解析器、处理静态资源等
         *         问题一:
         *             IOC容器如何初始化?
         *                 Java工程:new ClassPathXmlApplicationContext("beans.xml");
         *                 Web工程:在web.xml文件中配置ContextLoaderListener这个监听器
         *         问题二:
         *             Handler和Service被创建了两次?
         *                 让Spring不扫描Handler
         *                 让SpringMVC只扫描Handler

    springmvc.xml

    <!-- 组件扫描 -->
        <!-- 子标签context:include-filter:用来设置只扫描那个包下的类
        -要让此标签生效,必须将父标签的use-default-filters的属性值改为false -->
        <context:component-scan base-package="com.atguigu.ss"  use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
    
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"></property>
            <property name="suffix" value=".jsp"></property>
        
        </bean>

    beans.xml

    <!-- 设置自动扫描的包 -->
        <context:component-scan base-package="com.atguigu.ss">
            <!-- 子标签context:exclude-filter:用来设置不扫描那个包下的类
            如果type的值是annotation,那么expression的值是注解的全类名
            如果type的值是assignable,那么expression的值是接口或实现类的全类名 -->
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan >

    web.xml

    <!-- 前端控制器 -->
        <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!-- Map all requests to the DispatcherServlet for handling -->
        <servlet-mapping>
            <servlet-name>springDispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
        <!-- 配置ContextLoaderListener监听器;  Web工程-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:beans.xml</param-value>
        </context-param>
    
        <!-- Bootstraps the root web application context before servlet initialization -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
  • 相关阅读:
    更新证书错误Code Sign error: Provisioning profile ‘XXXX'can't be found
    解决Xcode 5下使用SVN出现 The operation couldn’t be completed. (NSURLErrorDomain error -1012.) 问题
    Android模拟器启动不了解决办法
    在AndroidManifest.xml文件中设置Android程序的启动界面方法
    Windows2008+MyEclipse10+Android开发环境搭配
    ADT下载地址整理
    android:inputType常用取值
    VS2010中使用Jquery调用Wcf服务读取数据库记录
    Linux手动安装netcore3.0
    StdOS之运行指示灯
  • 原文地址:https://www.cnblogs.com/shengyang17/p/10217425.html
Copyright © 2020-2023  润新知