Spring 入门

环境搭建

这一章通过具体的项目,加深对 IOC(控制反转)和 DI(依赖注入)的理解。
完整项目地址:spring_study

  • 导入依赖
    这里导入 spring-webmvc 就行,会自动加载其它 aop、beans、core、context等依赖。

    <dependencies>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>5.2.5.RELEASE</version>
          </dependency>
    
          <!--进行单元测试-->
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
          </dependency>
      </dependencies>
  • 项目结构

    tQn7BASvXa.png!large
  • 创建两个实体类 Adderss,Student 便于之后演示,这里只展示具体属性。

    public class Student {
      private String name;
      private Address address;
      private String[] books;
      private List<String> hobbies;
      private Map<String,String> card;
      private Set<String> games;
      private String wife;
      private Properties info;
    }
    public class Address {
    private String address;
    }

    到这里,其实和平时项目创建没区别,在没有使用 Spring 时,我们创建对象是自己创建的,如测试类代码所示:

    @Test
    public void test() {
      Student student = new Student();
      student.setName("hudu");
    }

    可以发现这是我们一般创建对象的过程,自己创建,并且给对象属性赋值,下面使用Spring之后就可明显感觉到什么是 IOC 和 DI 了。

  • 初步配置 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
          https://www.springframework.org/schema/beans/spring-beans.xsd">
      <!--
      id : bean 的唯一标识符,也就是相当于对象名
      class : bean 对象所对应的全限定名:包名+类名
      name : 类中的属性名
      value : 注入的属性的值
      -->
      <bean id="student" class="com.hudu.pojo.Student">
          <property name="name" value="hudu"/>
      </bean>
    </beans>

    上面对 applicationContext.xml 文件进行了简单的初步配置,此时再次获取Student对象和给对象属性赋值已经发生了变化。

@Test
    public void test() {
        //获取ApplicationContext:拿到Spring的容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = context.getBean("student", Student.class);
        System.out.println(student.getName());
    }

可以看出,我们的对象都在 Spring 中管理了,我们要使用,直接去里面取出来就行,这个其实就是 IOC 和 DI 的实现。下面进行进一步的讲解,IOC 创建对象的几种方法,总共三种。

  • 上面已经讲了第一种,直接通过参数名设置,即

    <bean id="student" class="com.hudu.pojo.Student">
          <property name="name" value="hudu"/>
    </bean>
  • 通过有参构造,下标赋值

    <bean id="address" class="com.hudu.pojo.Address">
      <constructor-arg index="0" value="The Earth"/>
    </bean>
  • 通过有参构造,通过类型创建,不建议使用

    <bean id="address" class="com.hudu.pojo.Address">
      <constructor-arg type="java.lang.String" value="The Earth"/>
    </bean>
  • 下面讲实体类各种类型的属性如何进行依赖注入,可以看到学生有很多属性,类型有 String、Map、Set等

    <bean id="address" class="com.hudu.pojo.Address">
          <property name="address" value="The Earth"/>
      </bean>
    
      <!--
      id : bean 的唯一标识符,也就是相当于对象名
      class : bean 对象所对应的全限定名:包名+类名
      name : 类中的属性名
      value : 注入的属性的值
      -->
      <bean id="student" class="com.hudu.pojo.Student">
          <!--第一种,普通值注入,value-->
          <property name="name" value="hudu"/>
          <!--第二种,Bean注入,ref-->
          <property name="address" ref="address"/>
          <!--数组注入-->
          <property name="books">
              <array>
                  <value>黑客与画家</value>
                  <value>从0到1</value>
                  <value>算法导论</value>
                  <value>深度学习</value>
              </array>
          </property>
          <!--List-->
          <property name="hobbies">
              <list>
                  <value>听歌</value>
                  <value>代码</value>
                  <value>电影</value>
              </list>
          </property>
          <!--map-->
          <property name="card">
              <map>
                  <entry key="身份证" value="2843198311239084"/>
                  <entry key="银行卡" value="3857928476381990"/>
              </map>
          </property>
          <!--set-->
          <property name="games">
              <set>
                  <value>LOL</value>
                  <value>COC</value>
                  <value>BOB</value>
              </set>
          </property>
          <!--null-->
          <property name="wife">
              <null/>
          </property>
          <!--properties-->
          <property name="info">
              <props>
                  <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
                  <prop key="url">jdbc//localhost:3306/test</prop>
                  <prop key="username">root</prop>
                  <prop key="password">123456</prop>
              </props>
          </property>
    </bean>

如果配置了多个 xml 文件,比如还配置了 beans.xml,可以讲两个xml文件进行整合

<import resource="beans.xml"/>

拓展注入方式

p命名空间和c命名空间,不能直接使用,需要导入xml约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

对于两个实体类,分别用c命名空间和p命名空间的方式注入

public class User {
    private String name;
    private int age;
}

public class User2 {
    private String name;
    private int age;

    public User2() {
    }

    public User2(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.hudu.pojo.User" p:name="hudu" p:age="18"/>

<!--c命名空间注入,通过有参构造器注入:construct-args-->
<bean id="user2" class="com.hudu.pojo.User" c:age="20" c:name="hudu"/>

bean的作用域

  • 单例模式(Spring默认机制),每次从容器中get时候都是同一个对象,不会创建新的。

    <bean id="user2" class="com.hudu.pojo.User" c:age="20" c:name="hudu" scope="singleton"/>
  • 原型模式:每次从容器中get的时候都会产生一个新的对象。

    <bean id="user2" class="com.hudu.pojo.User" c:age="20" c:name="hudu" scope="prototype"/>
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

写的很详细!👍

3周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!