Spring初识之bean、IoC、DI

环境准备

1、创建maven项目,加入依赖(如何创建maven项目?)

<dependencies>
    <!-- Spring 需要的依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <!-- 日志需要的依赖 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
</dependencies>

2、实际导入的jar包
在这里插入图片描述
3、创建
org.springframework.context.ApplicationContext 接口是常用的 Spring IoC 容器,负责实例化、配置、及装配 bean 的。它是 org.springframework.beans.factory.BeanFactory 的子接口,也是我们通常所讲的 bean 工厂。

这个接口有需要的实现类,我们使用org.springframework.context.support.ClassPathXmlApplicationContext 进行我们的练习。

3.1 新建Main.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
	public static void main(String[] args) {
	ApplicationContext context = new
	ClassPathXmlApplicationContext("applications.xml");
	}
}

3.2 新建applications.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">
</beans>

运行Main中的main方法如果没有报错,就证明已经创建成功。

一、Spring是什么?

Spring是一个Java Web开发框架,是一个轻量级的应用框架。

Spring以 IoC(Inverse of Control,控制反转)AOP(Aspect Oriented Programming,面向切面编程) 为内核,使用Bean容器来管理Java对象。

Spring框架的优点:

在这里插入图片描述

二、Spring体系结构

Spring包含很多框架,一般说Spring指的就是Spring Framework
在这里插入图片描述

三、Bean

3.1 Spring DI(依赖注入)

DI的实现方式有两种,构造注入和属性注入。

构造注入:指 IoC 容器使用构造方法注入被依赖的实例。必须有有参构造 方法
在这里插入图片描述

属性注入:指IoC 容器使用setter方法注入被依赖的实例。
在这里插入图片描述

3.2 Spring Bean的配置及常用属性

作为 Spring 核心机制的依赖注入,改变了传统的编程习惯,对组件的实例化不再由应用程序完成,转而交由 Spring 容器完成,在需要时注入应用程序中,从而对组件之间依赖关系进行了解耦。这一切都离不开 Spring 配置文件中使用的 元素。

Spring 容器可以被看作一个大工厂,而 Spring 容器中的 Bean 就相当于该工厂的产品。如果希望这个大工厂能够生产和管理 Bean,这时则需要告诉容器需要哪些 Bean,以及需要以何种方式将这些 Bean 装配到一起。

Spring 配置文件支持两种不同的格式,分别是 XML 文件格式和 Properties 文件格式。

通常情况下,Spring 会以 XML 文件格式作为 Spring 的配置文件,这种配置方式通过 XML 文件注册并管理 Bean 之间的依赖关系。

定义Bean的实例代码:

<?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">

    <!--通过bean标签定义bean对象,Spring Bean容器是通过id来管理的,
            id相当于bean的名称,Spring可以通过id找到bean对象,
            如果没有提供id,默认以类名首字母小写为id
            默认是单例模式
            -->
    <!--通过无参的构造方法,创建一个对象,如果该类型没有无参的构造方法就会报错-->
    <!--这里的操作就相当于 new String(); -->
    <bean id="s1" class="java.lang.String">
        <constructor-arg value="value1"/>
    </bean>
</beans>

常用属性的作用

属性名称描述
id是一个 Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成
class该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,使用类的全限定名
scope用于设定 Bean 实例的作用域,其属性值有 singleton(单例)、prototype(原型)、request、session 和 global Session。其默认值是 singleton
constructor-arg可以使用此元素传入构造参数进行实例化
property用于调用 Bean 实例中的 Setter 方法完成属性赋值,从而完成依赖注入
refproperty 和 constructor-arg 等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用
valueproperty 和 constractor-arg 等元素的子元素,用于直接指定一个常量值
list用于封装 List 或数组类型的依赖注入
set用于封装 Set 类型属性的依赖注入
map用于封装 Map 类型属性的依赖注入
entry用于设置一个键值对

3.3 Bean的实例化

3.4 Bean的作用域

3.4.1 作用域的种类

(1)singleton

单例模式,通过singleton定义的bean,在Spring容器中只有一个实例,这也是bean的默认作用域。

(2)prototype

原型模式,每次通过 Spring 容器获取 prototype 定义的 Bean 时,容器都将创建一个新的 Bean 实例。

(3)request

在一次 HTTP 请求中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Request 内有效。

(4)session

在一次 HTTP Session 中,容器会返回该 Bean 的同一个实例。而对不同的 HTTP 请求,会返回不同的实例,该作用域仅在当前 HTTP Session 内有效。

(5)global Session

在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。

3.4.2 singleton 作用域

singleton 是 Spring 容器默认的作用域,当一个 Bean 的作用域为 singleton 时,Spring 容器中只会存在一个共享的 Bean 实例,并且所有对 Bean 的请求,只要 id 与该 Bean 定义相匹配,就只会返回 Bean 的同一个实例。

3.4.3 prototype 作用域

使用 prototype 作用域的 Bean 会在每次请求该 Bean 时都会创建一个新的 Bean 实例。因此对需要保持会话状态的 Bean应该使用 prototype 作用域。

3.5 Bean的生命周期

Spring容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。

而对于 prototype 作用域 的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。

3.6 基于xml装配Bean

Spring 基于 XML 的装配通常采用两种实现方式,即设值注入(Setter Injection)和构造注入(Constructor Injection)。

在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过 Java 的反射机制调用 setXxx() 方法进行属性的注入。因此,设值注入要求一个 Bean 的对应类必须满足以下两点要求。

  • 必须提供一个默认的无参构造方法。
  • 必须为需要注入的属性提供对应的 setter 方法。

3.6.1 基于 XML 方式的 Bean 的装配过程

1、创建Fruit类(在项目src/main/java目录下创建hao包,在包中创建Fruit类和Fruit2类)

package hao;

/**
 * Demo class
 *
 * @author haozhang
 */
public class Fruit {
    private String name;
    private Double price;

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

package hao;

/**
 * Demo class
 *
 * @author haozhang
 */
public class Fruit2 {
    private String name;
    private Double price;

    public Fruit2(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

2、创建Spring配置文件(在resource目录下创建applications.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">

    <bean id="fruit1" class="hao.Fruit">
        <property name="name" value="apple"/>
        <property name="price" value="2.5"/>
    </bean>

    <bean id="fruit2" class="hao.Fruit2">
        <constructor-arg name="name" value="orange"/>
        <constructor-arg name="price" value="1.5"/>
    </bean>
</beans>

3、创建测试类

public class Main {
    public static void main(String[] args) {
        //Spring开启容器的方式:ApplicationContext 应用上下文(可以配置管理Bean对象,及其他的工作)
        //ClassPathXmlApplicationContext 根据classPath路径,指定一个xml文件(配置文件),
        // 并根据配置文件完成配置工作(如:Bean的实例化)
        ApplicationContext context = new
                ClassPathXmlApplicationContext("applications.xml");

        Fruit fruit1 = (Fruit) context.getBean("fruit1");
        System.out.println(fruit1);

        Fruit2 fruit2 = (Fruit2) context.getBean("fruit2");
        System.out.println(fruit2);
    }
}

4、运行查看结果
在这里插入图片描述

3.6.2 基于Annotation装配Bean

3.6.2.1 @Autowired

这是Spring框架提供的注解。

我们使用@Configuration注解一个类来定义配置类,

@Configuration
public class AppConfig {

    @Bean
    public Map<Integer, Integer> test() {
        Map<Integer, Integer> map = new HashMap<>(16);
        map.put(1, 100);
        map.put(2, 200);
        return map;
    }
}

我们使用@Controller注解一个类用来描述Bean,然后使用Autowired装配Bean

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    Map<Integer, Integer> test;
    public Object login() {
        return test;
    }
}

我们在学习基于xml配置bean的时候已经知道,一个类型有多个实例对象时,我们通过bean名称获取bean对象是没有什么问题的,但是通过类型去获取bean的时候就会出错。

再通过@Autowired配置bean时也是一样的,如果bean的类型有多个,我们通过类型去获取bean的时候就需要搭配 @Qualifier 去使用,在Qualifier中注明bean的名称。

假设我们有多个User类型的Bean

    @Autowired
    @Qualifier("user1")
    private User user; 
    public User user1() {
        return user;
    }
3.6.2.2 @Resource

@Resource是JDk提供的注解,表示资源。

    @Resource
    Map<Integer, Integer> test;
    public Object login() {
        return test;
    }

一个类型有多个bean对象时就需要在@Resource中注明bean对象的id

    @Resource(name = "user1")
    private User user; 
    public User user1() {
        return user;
    }

四、Spring IoC

Inversion of Control(控制反转,缩写为IoC),是面向对象的一种设计原则,降低计算机代码之间的耦合度。

IoC是指在程序开发的过程中,实例不再由调用者创建,而是由Spring容器创建,Spring容器负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了Spring容器中,控制权发生了反转。

对象的生命周期不再由程序管理,而是交给Spring的Bean容器,控制权发生了反转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值