• 深入学习Spring框架(一)- 入门


    1.Spring是什么?

      Spring是一个JavaEE轻量级的一站式开发框架。
        JavaEE: 就是用于开发B/S的程序。(企业级)
        轻量级:使用最少代码启动框架,然后根据你的需求选择,选择你喜欢的模块使用。
        重量级:早期有的EJB,开发一个HelloWorld程序都需要引入EBJ的全部模块
        一站式:Spring框架提供涵盖了JavaEE开发的表示层,服务层,持久层的所有组件功能。也就是说,原则上,学完一套Spring框架,不用其他框架就可以完成网站一条流程的开发。但是Spring仍然可以和其他的框架无缝整合。

    2.Spring的优点

      轻量:Spring 是轻量的,就是除内核模块(4个jar),其他模块由开发者自由选择使用,同时支持整合其他框架。也可以称为就是可插拔式开发框架,像插头和插座一样,插上就用。这就是Spring框架核心理念(Ioc)。
      控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
      面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
      容器:Spring 包含并管理应用中对象的生命周期和配置。
      MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
      事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
      异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

    3.Spring的作用

      Spring强调的理念是,轻量级。Spring的轻量级主要体现在模块的可插拔,Spring提供的功能模块,除了内核模块以外,开发人员可以选择性使用。所以,Spring框架在现实开发中,主要的功能用于整合各种开发框架开发项目。

    4.Spring框架包

      Spring官方网站:https://spring.io/

      4.1 下载

      Spring官方提供的Maven方式的项目下载:https://start.spring.io/
      但是基于简单入门的原则,我们要通过导入包的方式来学习。需要下载框架的zip包
      地址为:http://repo.springsource.org/libs-release-local/org/springframework/spring/

      4.2 目录说明

      根目录:

      

      jar包:

      

      包说明:

    包名 说明
    spring-aop-4.3.2.RELEASE.jar 实现了AOP的支持
    spring-aspects-4.3.2.RELEASE.jar AOP框架aspects支持包
    spring-beans-4.3.2.RELEASE.jar 内核支撑包,实现了处理基于xml对象存取
    spring-context-4.3.2.RELEASE.jar  内核支撑包,实现了Spring对象容器
    spring-context-support-4.3.2.RELEASE.jar  容器操作扩展包,扩展了一些常用的容器对象的设置功能
    spring-core-4.3.2.RELEASE.jar  内核支撑包,Spring的内核
    spring-expression-4.3.2.RELEASE.jar  内核支撑包,实现了xml对Spring表达式的支持
    spring-instrument-4.3.2.RELEASE.jar  提供了一些类加载的的工具类
    spring-instrument-tomcat-4.3.2.RELEASE.jar  提供了一些tomcat类加载的的工具类,实现对应Tomcat服务的调用
    spring-jdbc-4.3.2.RELEASE.jar  SpringJDBC实现包,一个操作数据库持久层的子框架
    spring-jms-4.3.2.RELEASE.jar  集成jms的支持,jms:Java消息服务。
    spring-messaging-4.3.2.RELEASE.jar  集成messaging api和消息协议提供支持
    spring-orm-4.3.2.RELEASE.jar  ORM框架集成包,实现了Hibernate,IBatis,JDO的集成。
    spring-oxm-4.3.2.RELEASE.jar  Spring OXM对主流O/X Mapping框架做了一个统一的抽象和封装。就是对应XML读写框架的支持
    spring-test-4.3.2.RELEASE.jar  Spring集成JUnit测试
    spring-tx-4.3.2.RELEASE.jar  事务代理的支持
    spring-web-4.3.2.RELEASE.jar  SpringWeb通用模块
    spring-webmvc-4.3.2.RELEASE.jar  SpringMVC子框架
    spring-webmvc-portlet-4.3.2.RELEASE.jar  Spring对门户技术(portlet)的支持
    spring-websocket-4.3.2.RELEASE.jar  Spring对websocket的支持

    注:红色部分为基础核心包,使用Spring必须导入

    5.入门实例

      Spring之所以可以实现模块的可插拔是支持依赖注入,所谓的依赖注入/控制反转就是不用new就可以创建对象。

      使用Spring框架不用new创建一个对象:

      1.创建项目并导入jar包:将Spring的基础支撑包和依赖的日志包复制到lib文件下,并且加入项目中

      

      2.创建配置文件
      在项目的src下面创建配置文件applicationContext.xml中并完成配置文件的约束

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

      3.创建对象到Spring容器中
      创建一个类

    package com.gjs.service;
    
    public class HelloSpringService {
        public void say() {
            System.out.println("你好!Spring");
        }
    }

      往applicationContext.xml配置文件中加入配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
             <!-- <bean id="" class = ""> 
              配置让spring管理类的对象的创建
              id : 唯一标识
              class :被管理类的全限定名
              -->  
            <bean id="HelloSpringService" class="com.gjs.service.HelloSpringService"/>
                
    </beans>

      测试类, 使用getBean方法获得容器中的对象。

    package com.gjs.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.gjs.service.HelloSpringService;
    
    public class TestSpring {
        @Test
        public void testName() throws Exception {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            HelloSpringService helloSpringService = context.getBean("HelloSpringService",HelloSpringService.class);
            helloSpringService.say();
        }
    }

    6.Spring容器的两个实现

    ClassPathXmlApplicationContext:通过classpath路径(相对路径)直接获得加载的xml文件(推荐使用)

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    FileSystemXmlApplicationContext:通过文件路径(绝对路径)来获得加载的xml文件。

    ApplicationContext context = new FileSystemXmlApplicationContext("D:\java\eclipse-workspace\spring1\src\applicationContext.xml");

    8.控制反转(IOC)和依赖注入(DI)(A)

      DI:Dependency Injection(依赖注入):

      依赖注入是指Spring创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象。

      IoC:Inverse of Control(控制反转):

      Spring号称是一个可以实现模块可插拔的JavaEE开发框架。而实现程序可插拔的核心理念就是控制反转。所谓的控制反转,就是将代码的调用权从调用方转移给被调用方(服务提供方)。不用修改调用方的的代码,只要修改配置文件就实现对象的切换。
      读作“反转控制”,更好理解,它不是什么技术,而是一种设计思想,好比于MVC。就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
      正控:若调用者需要使用某个对象,其自身就得负责该对象的创建。
      反控:调用者只管负责从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架。
      控制反转(Ioc),就是依赖注入加上面向接口的编程思想的实现

      示例:

      整体结构:

      

      CustomService接口:

    package com.gjs.service;
    
    public interface CustomeService {
        public void say();
    }

      实现类CustomServiceImpl1:

    package com.gjs.service.impl;
    
    import com.gjs.service.CustomeService;
    
    public class CustomServiceImpl1 implements CustomeService {
    
        @Override
        public void say() {
            System.out.println("CustomerServiceImpl1.say()");
        }
    }

      实现类CustomServiceImpl2:

    package com.gjs.service.impl;
    
    import com.gjs.service.CustomeService;
    
    public class CustomServiceImpl2 implements CustomeService {
    
        @Override
        public void say() {
            System.out.println("CustomerServiceImpl2.say()");
        }
    }

      调用方 CustomClient:

    package com.gjs.client;
    
    import com.gjs.service.CustomeService;
    
    public class CustomClient {
        //1.声明一个接口引用类型
        private CustomeService customeService;
        //2.spring的依赖注入(DI)需要有一个set方法
        public void setCustomeService(CustomeService customeService) {
            this.customeService = customeService;
        }
        
        public void say() {
            customeService.say();
        }
    }

      配置文件 applicationContext.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
             <!-- 
            <bean id="" class = ""> 
              配置让spring管理类的对象的创建
              id : 唯一标识
              class :被管理类的全限定名
              -->  
            <bean id="client" class="com.gjs.client.CustomClient">
                <!-- 依赖注入(DI) :注入被调用方 
                  <property name="" value/ref=""/>
                             位置:
                      name : 是set方法确定的属性,不是成员变量
                          确定属性 : setXxx 方法去掉set前缀 ,剩余部分首字母小写
                             参数:        
                      value : 值类型注入(字符串,基本数据类型)
                      ref :引用数据类型(对象), 对应bean的id
               -->
                <property name="customeService" ref="ServiceImpl1"/>
            </bean>
            
            <bean id="ServiceImpl1" class="com.gjs.service.impl.CustomServiceImpl1"/>
            <bean id="ServiceImpl2" class="com.gjs.service.impl.CustomServiceImpl2"/>    
    </beans>

      测试类:

    package com.gjs.test;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.gjs.client.CustomClient;
    import com.gjs.service.CustomeService;
    
    public class TestSpring {
        @Test
        public void testName() throws Exception {
            //1.读取配置文件,创建Spring容器
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            //获取调用方 CustomClient对象
            CustomClient client = context.getBean("client", CustomClient.class);
            //调用CustomClient对象的say()方法
            client.say();
        }
    }

      应用:

      Spring框架又被称为容器框架,即通过控制反转将各个框架的对象创建交给Spring管理,然后通过依赖注入在层之间传递参数整合框架,并达到低耦合的目的。

      

    9.标签说明

      9.1 bean标签

      作用:用于声明一个类,在启动Spring框架的时候根据该配置的类创建对象到容器里面

    <bean id="someBean" class="com.gjs.pojo.SomeBean" scope="prototype"></bean>

    id:设置对象名(唯一标识符)(推荐使用)
    name:设置对象名(唯一标识符),与id的区别是可以有多个名称,每个名称用逗号隔开。
    class:指定对象对应的类
    scope:用于设置的对象的作用范围,可选参数如下:

      

    在Web开发的三层架构中的使用
      Web层:一般都是多例
      Service层 :单例
      DAO层 :单例

      9.2 alias 别名标签  

      作用:为已配置的bean设置别名

    bean id="user" name="test" class="com.gjs.pojo.User"/>
    <alias name="user" alias="user1"/> 

    name:必要属性, 代表为哪一个bean配置别名, 此属性的值为其他bean标签的id或name属性值
    alias: 必要属性,命名的别名

    10.实例化Bean的四种方式

      1.构造器实例化(无参数构造器):(最常用)

    public class SomeBean {
        public SomeBean() {
            System.out.println("SomeBean.SomeBean()");
        }
    }
    <bean id="someBean" class="com.gjs.pojo.SomeBean"/>

      2.通过静态方法工厂创建(C)

    public class SomeBean {
        public SomeBean() {
            System.out.println("SomeBean.SomeBean()");
        }
    }
    public class SomeBeanFacotry {
        //静态工厂方法
        public static SomeBean getSomeBean() {
            System.out.println("执行静态工厂方法");
            return new SomeBean();
        }
    }
    <bean id="someBean" class="com.gjs.pojo.SomeBeanFacotry" factory-method="getSomeBean"/>

      3.通过实体工厂创建(C)

    public class SomeBean {
        public SomeBean() {
            System.out.println("SomeBean.SomeBean()");
        }
    }
    public class SomeBeanFacotry {
        //实例工厂方法
        public SomeBean getSomeBean() {
            System.out.println("执行实例工厂方法");
            return new SomeBean();
        }
    }
    <bean id="someBeanfactory" class="com.gjs.pojo.SomeBeanFactory"/>

    <bean id="someBean" factory-bean="someBeanfactory" factory-method="getSomeBean"/>

      4.实现FactoryBean接口实例化:实例工厂变种
      实现FactoryBean接口,MyBatis和Spring集成就是使用的这种方式。此种方式,如果没有使用Bean对应的对象,Spring就不会自动创建,只有在使用的时候Spring才会创建对应的对象

    public class SomeBean {
        public SomeBean() {
            System.out.println("SomeBean4.SomeBean4()");
        }
    }
    public class SomeBeanObjectFactory implements FactoryBean<SomeBean>{
        //返回的泛型类型对应的对象
        @Override
        public SomeBean getObject() throws Exception {
            SomeBean bean = new SomeBean();
            return bean;
        }
    }
    <bean id="someBean" class="cn.zj.domian.SomeBeanObjectFactory"/>

    11.初始化和销毁方法

    <bean id="someBean" class="......" 
       <init-method="该类中初始化方法名"/> 
      <destroy-method="该类中销毁方法名"/>
    </bean>

      init-method:bean生命周期初始化方法,对象创建后就进行调用
      destroy-method:容器被销毁的时候,如果bean被容器管理,会调用该方法。

    12.依赖注入的四种方法

      1.setter注入,(属性注入)(常用)

    使用setter注入:

    1,使用bean元素的<property>子元素设置;

    1.简单类型值,直接使用value赋值;
    2.引用类型,使用ref赋值;
    3.集合类型,直接使用对应的集合类型元素即可。

    2,spring通过属性的set方法注入值;
    3,在配置文件中配置的值都是string,spring可以自动的完成类型的转换

    示例:

    员工类

    public class Employee {
        private Integer age;
        private String name;
        private Department dept;
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Department getDept() {
            return dept;
        }
        public void setDept(Department dept) {
            this.dept = dept;
        }
        @Override
        public String toString() {
            return "Employee [age=" + age + ", name=" + name + ", dept=" + dept + "]";
        }    
    }

      部门类

    public class Department {
        private Integer id;
        private String name;
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

      配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 员工 -->
        <bean id="employee" class="com.gjs.pojo.Employee" >
            <!-- setter方法注入: 属性注入 
                <property name="" value="">
                name : 属性名称
                value : 基本数据类型+String类型的值注入
                ref : 引用类型(对象类型)的注入
                value 和ref 只能二选一
            -->
            <property name="age" value="18"></property>
            <property name="name" value="张三"></property>
            <property name="dept" ref="dept"></property>
        </bean>
        <!-- 部门 -->
        <bean id="dept" class="com.gjs.pojo.Department" >
               <property name="id" value="1"/>
               <property name="name" value="开发部"/>
       </bean>
    </beans>

    2.构造器注入

    使用bean元素的<constructor-arg>子元素设置:

    1.默认情况下,constructor-arg的顺序就是构造器参数的顺序
    2. constructor-arg的属性

    name : 构造方法参数的名称
    index :参数的位置从 0 开始
    value :值类型注入
    ref :引用类型注入
    type : 参数的数据类型

    3.一般在一个类必须依赖另一个类才能正常运行时,才用构造器注入

     

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
     
         <!-- 配置部门 -->
         <bean id="department" class="com.gjs.pojo.Department">
             
             <constructor-arg name="id"  value="2"/>
             <constructor-arg name="name"  value="研发部"/>
         </bean>
         
         <!-- 配置员工 -->
         <bean id="emp" class="com.gjs.pojo.Employee">
             <!-- 依赖注入 :构造器注入 -->
             <constructor-arg name="id" value="1"/>
             <constructor-arg name="name" value="张三"/>
             <constructor-arg name="dept" ref="department"/>
         </bean>
    </beans>

      3.p命名空间注入

      使用p命名空间注入先在约束上面引入 p标签
      xmlns:p="http://www.springframework.org/schema/p"

    <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
            
         <!-- 配置部门 -->
         <bean id="department" class="com.gjs.pojo.Department" 
         p:id="3"
         p:name="销售部"/>
         
         <!-- 配置员工 -->
         <bean id="emp" class="com.gjs.pojo.Employee" 
         p:id="1"
         p:name="张三"
         p:dept-ref="department"/>
    </beans>

    4.集合类型值注入
    用于处理:
      1.键值对 Map 、Properties
      2.数组
      3.集合Set、List

    public class CollectionBean {
        private Set<String> set;
        private List<String> list;
        private String[] array;
        private Map<String, String> map;
        private Properties prop; //读取本地 xxx.properties文件(本质就是一个Map集合)
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
            
         <bean id="collectionBean" class="cn.zj.spring.pojo.CollectionBean">
             
             <!-- setter(属性)方法注入 -->
             <!-- 1.数组 -->
             <property name="arr">
                 <array>
                     <value>AAA</value>
                     <value>BBB</value>
                 </array>
             </property>
             
             <!-- 2.set集合 -->
             <property name="set" >
                 <set>
                     <value>AAA</value>
                     <value>AAA</value>
                     <value>BBB</value>
                 </set>
             </property>
             
             <!-- 3.list集合 -->
             <property name="lsit">
                 <list>
                     <value>list1</value>
                     <value>list1</value>
                     <value>list2</value>
                 </list>
             </property>
             <!-- 4. map集合 -->
             <property name="map">
                 <map>
                     <entry key="key1" value="value1"/>
                     <entry key="key2" value="value2"/>
                 </map>
             </property>
             <!-- 5.properties 集合 -->
             <property name="prop">
                 <props>
                     <prop key="propKey1">propValue1</prop>
                     <prop key="propKey2">propValue2</prop>
                 </props>
             </property>
         </bean> 
    </beans>

    13.获得properties文件的值

      1.导入命名空间方法
      将命名空间和约束重新拷贝一份,将对于的全部替换成 context,然后关联context本地schema约束

    <?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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="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.xsd
        ">
        
    </beans>

      2.导入Mysql驱动包和druid连接池jar包

      

      3.applicationContext.xml配置

    <?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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            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.xsd
            ">
            
          <!-- 使用context 读取配置文件到spring容器中
             <context:property-placeholder location=""/>
             location : db.properties文件的位置,必须加上 classpath: 作为前缀
        -->
          <context:property-placeholder location="classpath:db.properties"/>
              <!-- 创建阿里巴巴druid连接池 -->
              <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
                  init-method="init" destroy-method="close"
              >
                  <!-- 属性注入 setter方法注入-->
                  <property name="driverClassName" value="${jdbc.driverClassName}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
                <!-- 最大连接数 -->
                <property name="maxActive" value="${jdbc.maxActive}"/>
          </bean>
      
    </beans>

      测试代码

    @Test
        public void testSave() throws Exception {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            
            DataSource dataSource = context.getBean(DataSource.class, "dataSource");
            Connection conn = dataSource.getConnection();
            System.out.println("数据库连接对象:"+conn);
        }
  • 相关阅读:
    OpenCV 环境搭建( Win7 32位 / VS2010 / OpenCV2.4.8 )
    OpenCV 简介
    计算机视觉简介
    使用 sigaction 函数实现可靠信号
    可靠信号机制
    信号机制的两个思考
    信号的接收和处理
    【angular5项目积累总结】列表多选样式框(1)
    数组相关方法积累(vueag等特别常用)
    Angular 4+ 修仙之路
  • 原文地址:https://www.cnblogs.com/gaojinshun/p/11156030.html
Copyright © 2020-2023  润新知