Spring学习(一)

一、IoC Container

1.1、IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

图片

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

图片

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

1.2、基础使用

1、创建maven项目,在pom.xml中导入jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.14</version>
</dependency>

2、编写一个Hello实体类

package com.rui.pojo;

public class Hello {
    private String name;

    public Hello() {
    }

    public Hello(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public void show(){
        System.out.println("Hello" + name);
    }
}

3、编写我们的spring文件 , 这里我们命名为beans.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就是java对象 , 由Spring创建和管理-->
   <bean id="hello" class="com.rui.pojo.Hello">
       <property name="name" value="Spring"/>
   </bean>

</beans>

4、在Test/java目录下编写测试类进行测试

@Test
public void test(){
   //解析beans.xml文件 , 生成管理相应的Bean对象
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   //getBean : 参数即为spring配置文件中bean的id .
   Hello hello = (Hello) context.getBean("hello");
   hello.show();
}

二、依赖注入

依赖注入(Dependency Injection,DI)。

  • 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .
  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .

使用Spring创建对象,在Spring中这些变成为bean。在配置文件被加载后,容器中的对象就已经被初始化了

2.1、构造器注入

有参构造器注入(constructor-arg属性):

第一种:根据index参数下标设置

<bean id="user" class="com.rui.pojo.User">
   <!-- index指构造方法 , 下标从0开始 -->
   <constructor-arg index="0" value="Spring"/>
</bean>

第二种:根据参数名字设置

<bean id="user" class="com.rui.pojo.User">
   <!-- name指参数名 -->
   <constructor-arg name="name" value="Spring"/>
</bean>

第三种:根据参数类型设置,不建议使用

<bean id="user" class="com.rui.pojo.User">
   <constructor-arg type="java.lang.String" value="Spring"/>
</bean>

2.2、set注入(重点)

要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型 , 没有set方法 , 是 is + 属性首字母大写.

set注入是使用property属性给对象的每一个name赋值(这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写)

类似:Hello hello = new Hello()
id=变量名
class=new的对象
property=给对象的每一个属性赋值

下面重点介绍这几个

bean | ref | idref | list | set | map | props | value | null

创建实体类Student、Adress类

package com.rui.pojo;

import java.util.*;

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


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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHhobbys() {
        return hhobbys;
    }

    public void setHhobbys(List<String> hhobbys) {
        this.hhobbys = hhobbys;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hhobbys=" + hhobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}
package com.rui.pojo;

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}

创建beans.xml文件,使用set注入

<bean id="student" class="com.rui.pojo.Student">
    ...
</bean>

普通注入

<property name="name" value="叶辰"/>

Bean注入

<property name="address" ref="address"/>
<bean id="address" class="com.rui.pojo.Address">
    <property name="address" value="鹤壁"/>
</bean>

数组注入

<property name="books">
    <array>
        <value>红楼梦</value>
        <value>水浒传</value>
        <value>西游记</value>
        <value>三国演义</value>
    </array>
</property>

list注入

<property name="hhobbys">
    <list>
        <value>听课</value>
        <value>上网</value>
    </list>
</property>

map注入

<property name="card">
    <map>
        <entry key="身份证" value="123123123"/>
        <entry key="手机号" value="123456789"/>
    </map>
</property>

Set注入

<property name="games">
    <set>
        <value>LOL</value>
        <value>COC</value>
    </set>
</property>

null

<property name="wife">
    <null/>
</property>

Properties

<property name="info">
    <props>
        <prop key="学号">1001</prop>
        <prop key="性别"></prop>
    </props>
</property>

2.3、p命名和c命名注入

p命名空间注入:property

c命名空间注入:通过构造器注入:constructor-arg

注:在使用时需要引入:

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

配置beans.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">


    <!-- p命名空间注入:property -->
    <bean id="user" class="com.rui.pojo.User" p:age="18"/>

    <!-- c命名空间注入:通过构造器注入:constructor-arg-->
    <bean id="user2" class="com.rui.pojo.User" c:age="18" c:name="小明"/>

</beans>

三、Spring配置

  • 别名

alias 设置别名 , 为bean设置别名 , 可以设置多个别名

<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>
  • Bean的配置
<!--bean就是java对象,由Spring创建和管理-->

<!--
   id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
   如果配置id,又配置了name,那么name是别名
   name可以设置多个别名,可以用逗号,分号,空格隔开
   如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;

class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
   <property name="name" value="Spring"/>
</bean>
  • import

团队的合作通过import来实现 .

<import resource="{path}/beans.xml"/>

3.1、Bean的其他属性

3.1.1、scopes

在写出的bean标签内添加 scope="singleton"

  • singleton 单例模式:(默认值)将单个 Bean 定义限定为每个 Spring IoC 容器的单个对象实例。
  • prototype 原型模式: 将单个 Bean 定义的作用域限定为任意数量的对象实例。
    request 将单个 Bean 定义的作用域限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 Bean 实例,该实例是在单个 Bean 定义后面创建的。仅在网络感知Spring的上下文中有效。ApplicationContext
    session 将单个 Bean 定义限定为 HTTP 的生命周期。仅在网络感知Spring的上下文中有效。SessionApplicationContext
  • application 将单个 Bean 定义的作用域限定为 的生命周期。仅在网络感知Spring的上下文中有效。ServletContextApplicationContext
  • websocket 将单个 Bean 定义的作用域限定为 的生命周期。仅在网络感知Spring的上下文中有效。WebSocketApplicationContext
3.1.2、autowire(自动装配)
  • autowire byName (按名称自动装配)
  • autowire byType (按类型自动装配)

autowire byName

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。可采用采用自动装配将避免这些错误,并且使配置简单化。

测试:

1、新建两个实体类,Cat Dog 都有一个叫的方法

public class Cat {
   public void shout() {
       System.out.println("miao~");
  }
}
public class Dog {
   public void shout() {
       System.out.println("wang~");
  }
}

2、新建一个用户类 User

public class User {
   private Cat cat;
   private Dog dog;
   private String str;
}

3、编写Spring配置文件

<bean id="dog" class="com.rui.pojo.Dog"/>
<bean id="cat" class="com.rui.pojo.Cat"/>

<bean id="user" class="com.rui.pojo.User">
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
<property name="str" value="qinjiang"/>
</bean>

4、修改bean配置,增加一个属性 autowire=“byName”

<bean id="user" class="com.rui.pojo.User" autowire="byName">
   <property name="str" value="yechen"/>
</bean>

小结:

当一个bean节点带有 autowire byName的属性时。

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
  2. 去spring容器中寻找是否有此字符串名称id的对象。
  3. 如果有,就取出注入;如果没有,就报空指针异常。

**autowire byType **

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。NoUniqueBeanDefinitionException

测试:

1、将user的bean配置修改一下 : autowire="byType"

2、在注册一个cat 的bean对象!

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="user" class="com.kuang.pojo.User" autowire="byType">
   <property name="str" value="qinjiang"/>
</bean>

4、测试,报错:NoUniqueBeanDefinitionException

5、删掉cat2,将cat的bean名称改掉!测试!因为是按类型装配,所以并不会报异常,也不影响最后的结果。甚至将id属性去掉,也不影响结果。

Spring学习笔记均参考于“狂神说”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶辰 .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值