深入浅出Spring IOC-2

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 深入浅出Spring IOC-2

深入浅出Spring IOC-2

前言:

上一篇文章我们介绍了Spring的IOC,即控制反转,Spring来创建对象,程序中需要使用对象时,直接通过Spring容器来获取对象,并通过DI完成对象之间的注入关系。今天我们继续来学习IOC的相关知识。

代码:

 

1.Spring中的bean是根据scope来生成的,表示bean的作用域。

 

scope有4种类型:

1.singleton:单例,表示通过Spring容器获取的该对象是唯一的。

2.prototype:原型,表示通过Spring容器获取的对象都是不同的。

3.reqeust:请求,表示在一次http请求内有效。

4.session:会话,表示在一个用户会话内有效。

 

3和4只适用于web项目,大多数情况下,我们只会使用singleton和prototype两种scope,并且scope的默认值是singleton。

 

我们通过一个例子来学习这两种配置的区别。

1.创建User实体类。

 

 


public class User {
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }   
    public User() {
         System.out.println("创建了User对象");
    }   </code><code style="font-family: Consolas, Inconsolata, Courier, monospace; color: #a9b7c6; background: #282b2e; padding: 0.5em; display: block !important; word-wrap: normal !important; word-break: normal !important; overflow: auto !important;">}

 

2.在spring.xml配置User的实例化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 http://www.springframework.org/schema/beans/spring-beans.xsd"

     bean id="user" class="com.southwind.entity.User"
        property name="id" value="1"/property
        property name="name" value="张三"/property
        property name="age" value="23"/property
     /bean

/beans

 

3.测试类中通过Spring容器获取两个User实例化对象user1和user2,并且通过==方法判断是否为同一个对象。

 


public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) applicationContext.getBean("user");
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user == user2);
    }
}

 

深入浅出Spring IOC-2

 

看到结果打印true,并且User的构造函数只执行了一次,表示user1和user2是同一个对象,所以scope默认值为singleton,即默认通过Spring容器创建的对象都是单例模式。

 

修改spring.xml中的配置,将scope改为prototype。

 


?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="user" class="com.southwind.entity.User" scope="prototype"
        property name="id" value="1"/property
        property name="name" value="张三"/property
        property name="age" value="23"/property
     /bean

/beans

 

执行代码,结果如下。

 

深入浅出Spring IOC-2

 

可以看到,调用了两次构造函数,并且==的结果为false,表示现在的user1和user2是两个对象。

 

2.Spring的继承,与Java的继承不一样,但思想很相似,子bean可以继承父bean中的属性。

 

看到这里,有人会问子bean可以继承父bean中的方法吗?

其实这里不存在方法的继承,Spring的继承是在对象层面进行操作的,即两个bean来自同一个类,所以方法是一样的,不存在继承关系。

 

1.spring.xml中配置两个User 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 http://www.springframework.org/schema/beans/spring-beans.xsd"

     bean id="user" class="com.southwind.entity.User"
        property name="id" value="1"/property
        property name="name" value="张三"/property
        property name="age" value="23"/property
     /bean

     bean id="user2" class="com.southwind.entity.User" parent="user"/bean

/beans

 

2.运行代码,结果如下。

 


User user2 = (User) applicationContext.getBean("user2");
System.out.println(user2);

 

 

深入浅出Spring IOC-2

 

可以看到,创建了两个User对象user1和user2,并且user2继承了user1的所有属性。

 

user2在继承user1所有属性的基础之上,还可以对属性进行覆盖,直接在spring.xml中添加property即可。

 


?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="user" class="com.southwind.entity.User"
        property name="id" value="1"/property
        property name="name" value="张三"/property
        property name="age" value="23"/property
     /bean

     bean id="user2" class="com.southwind.entity.User" parent="user"
        !-- 覆盖name属性 --
        property name="name" value="李四"/property
     /bean

/beans

 

再次运行代码,看到结果。

 

深入浅出Spring IOC-2

 

name属性已经被修改为李四,完成覆盖。

 

有同学可能会问,Spring中的bean能不能在不同类之间继承?

答案是可以,但是需要这两个类的属性列表完全一致,否则会报错,实际开发中并不会使用到这种方式。

 

3.Spring的依赖。

 

与继承类似,依赖也是bean和bean之间的一种关联方式,配置依赖关系后,被依赖的bean一定先创建,再创建依赖的bean。

 

我们还是通过代码来理解。

1.创建Car实体类。

 


public class Car {
    private int id;
    private String brand;

    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Car() {
        System.out.println("创建了Car对象");
    }

}

 

2.在spring.xml中配置User bean,Car 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 http://www.springframework.org/schema/beans/spring-beans.xsd"

     bean id="user" class="com.southwind.entity.User"
        property name="id" value="1"/property
        property name="name" value="张三"/property
        property name="age" value="23"/property
     /bean

     bean id="car" class="com.southwind.entity.Car"
        property name="id" value="1"/property
        property name="brand" value="宝马"/property
     /bean

/beans

 

3.测试类中获取两个bean。

 


public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) applicationContext.getBean("user");
        Car car = (Car) applicationContext.getBean("car");
    }
}

 

看到结果,先创建User,后创建Car,这是由spring.xml中bean的配置顺序来决定的,先到先得,先配置User bean,所以先创建了User对象。

 

 

深入浅出Spring IOC-2

 

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 深入浅出Spring IOC-2


 上一篇
深入浅出Spring IOC-1 深入浅出Spring IOC-1
前言: Spring是一个企业级开发框架,为解决企业级项目开发过于复杂而创建的,框架的主要优势之一就是分层架构,允许开发者自主选择组件。   Spring的两大核心机制是IOC(控制反转)和AOP(面向切面编程), 从开发的角度讲,
2021-04-05
下一篇 
SpringMVC笔记(1)——快速入门 SpringMVC笔记(1)——快速入门
前言: SpringMVC是什么?   SpringMVC是目前最好的实现MVC设计模式的框架,是Spring框架的一个分支产品,以SpringIOC容器为基础,并利用容器的特性来简化它的配置。SpringMVC相当于Spri
2021-04-05