springIOC第2弹-IoC和DI的概念和Bean标签的使用


  • 0x01_spring中的Bean的概念

  • 0x02_对对象的“管理”

  • 0x03_Bean标签

    • 准备实体类

    • applicationContext.xml

    • bean标签

    • 测试方法


spring中的IoC和DI的概念和Bean标签的使用

关于Spring IOC的介绍,参考我这个专栏上一篇的介绍。这篇从Spring中的Bean了解说起,聊聊对于对象创建IOC和对象属性赋值DI,以及这两者之间的关系。最后来阐述bean标签中几个属性及其值的含义。

0x01_spring中的Bean的概念

Bean(汉译是咖啡豆). 又称JAVABean.其实就是JAVA程序程序中的一个个对象,所以Bean的管理其实就是spring对于JAVA程序中的对象的管理

区别bean和pojo:

  • bean:JavaBean 是一种JAVA语言写成的可重用组件。JavaBean符合一定规范编写的Java类,不是一种技术,而是一种规范。大家针对这种规范,总结了很多开发技巧、工具函数。符合这种规范的类,可以被其它的程序员或者框架使用。它的方法命名,构造及行为必须符合特定的约定:

    因为这些要求主要是靠约定而不是靠实现接口,所以许多开发者把JavaBean看作遵从特定命名约定的POJO。

    1. 所有属性为private。
    2. 这个类必须有一个公共的缺省构造函数。即是提供无参数的构造器。
    3. 这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。
    4. 这个类应是可序列化的。实现serializable接口。
  • pojo:Plain Ordinary Java Object,简单普通的java对象。主要用来指代那些没有遵循特定的java对象模型,约定或者框架的对象。POJO往往是指:有一些private的参数作为对象的属性,然后针对每一个参数定义get和set方法访问的接口。没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。

  • 两者的区别:

    POJO其实是比javabean更纯净的简单类或接口。POJO严格地遵守简单对象的概念,而一些JavaBean中往往会封装一些简单逻辑。

    POJO主要用于数据的临时传递,它只能装载数据, 作为数据存储的载体,而不具有业务逻辑处理的能力。

    Javabean虽然数据的获取与POJO一样,但是javabean当中可以有其它的方法。

0x02_对对象的“管理”

管理涉及2个方面:

IOC:对象的创建,IOC 叫做控制反转,就是Spring给我们创建对象,然后我们直接用,不用自己NEW,前面已经解释过

IOC处理的是对象如何创建的问题

DI:属性的赋值,Dependency Injection,即“依赖注入” 就是创建属性时给对象属性赋值 对象功能的实现往往要依赖属性的值,那么给对象属性赋值就可以说成是依赖注入 由于对象属性不仅仅是基本数据类型,还可能是其他类,或者引用类型 (比如另一个对象) 那么依赖注入将会把更多的对象之间的关系整理到一起,可以行程一个庞大的依赖关系 DI处理的是对象的属性赋值和互相依赖的关系

注意:没有IOC就没有DI!!!先要有对象的创建,才能给属性赋值。

应用程序代码从Ioc Container中获取依赖的Bean,注入到应用程序中,这个过程叫 依赖注入(Dependency Injection,DI) ; 所以说控制反转是通过依赖注入实现的,其实它们是同一个概念的不同角度描述。通俗来说就是IoC是设计思想,DI是实现方式

0x03_Bean标签

创建一个maven 模块,不选择任何的archetype,在pom.xml中导入依赖:

    <dependencies>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>

创建完成后,请检查maven的版本以及settings.xml配置文件。

准备实体类

为了测试,了解容器获取时对象创建的细节,在一些方法和构造方法中,写了一些打印语句:

package com.bones.bean;
/**
* @author : bones
* @version : 1.0
*/

public class User {
private Integer userid;
private String username;
private String password;

public User(Integer userid, String username, String password) {
System.out.println("allArgConstructor");
this.userid = userid;
this.username = username;
this.password = password;
}

public User() {
System.out.println("noArgConstructor");
}

public Integer getUserid() {
System.out.println("getUserid");
return userid;
}

public String getUsername() {
System.out.println("getUsername");
return username;
}

public String getPassword() {
System.out.println("getPassword");
return password;
}

@Override
public String toString() {
return "User{" +
"userid=" + userid +
", username='" + username + ''' +
", password='" + password + ''' +
'}';
}
}

applicationContext.xml

准备Spring的配置文件,目前仍旧是xml形式

springIOC第2弹-IoC和DI的概念和Bean标签的使用
image-20221026202139154

关于这个文件的命名问题,没有死的规定,但是基本都是springxxx.xml或者applicationxxx.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>

IDEA默认的创建内容如上。

bean标签

先写bean标签:

<bean id="user1" class="com.bones.bean.User"/>

之前演示的例子中基本都是只写了2个属性idclass,现在介绍一下其他属性:

  • name 和id类似(早期),一般不用

  • scope 控制对象单例多例和使用范围 jar项目两个值,web项目可以一共有5个选择的值

    singleton作用域(scope 默认值), Spring IOC容器中只会存在一个共享的bean实例   (单例模式)  可以获取两个user看看等不等  常用的,省内存

    prototype作用域部署的bean,每一次获取都会产生一个新的bean实例,相当与一个new的操作

    request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效

    session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效

    global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义

  • lazy-init 懒加载(=true)时 调用getBean的时候再去实例化对象 ,而不是在获取容器的时候初始化,可以测试一下看看  这个用法有争议,个人建议false,但是这个是架构师考虑的

测试方法

下面对于上面的三个属性进行测试:

scope属性

    <bean id="user1" class="com.bones.bean.User" scope="singleton"/>

scope的默认值是singleton,由容器创建的对象是单例的。

测试:

@Test
public void testBeanTag(){
//获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取对象
User user1 = applicationContext.getBean("user1", User.class);
User user2 = applicationContext.getBean("user1", User.class);
System.out.println("user1==user2 = " + (user1 == user2));
}

springIOC第2弹-IoC和DI的概念和Bean标签的使用

小结:

1.控制反转时,容器创建对象的时候,调用的是空的构造方法。

2.容器默认创建的对象是单例的,也就是说bean标签的scope属性是默认值是singleton

目前项目是jar项目,scope取值只有两个选择,还有一个可选值是prototype

<bean id="user1" class="com.bones.bean.User" scope="prototype"/>

测试结果:

springIOC第2弹-IoC和DI的概念和Bean标签的使用

也就是说,scope="prototype"创建的对象不是单例的,是基于一个原型的,在创建时,会多次调用构造方法。

lazy-init

默认值是false,默认不是懒加载

<bean id="user1" class="com.bones.bean.User" lazy-init="false"/>

这个测试需要打断点:

springIOC第2弹-IoC和DI的概念和Bean标签的使用
image-20221026210203965

看到:在容器还没有 获取对象之前,对象的创建已经完成。

现在将lazy-init修改为true

springIOC第2弹-IoC和DI的概念和Bean标签的使用
image-20221026210314736

容器对于对象的创建“懒加载”了,只有当调用getBean方法时,才会创建对象。


原文始发于微信公众号(小东方不败):springIOC第2弹-IoC和DI的概念和Bean标签的使用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/47077.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!