纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

SpringIOC Bean对象 Spring IOC中的Bean对象用法

.SOLO.   2021-09-13 我要评论
想了解Spring IOC中的Bean对象用法的相关内容吗.SOLO.在本文为您仔细讲解SpringIOC Bean对象的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Spring,IOC,Bean对象下面大家一起来学习吧

Spring IOC中的Bean对象

一、Bean是什么

突然发现提到了好多次Bean居然忘记了讲Bean是什么没事现在讲也不晚Java中的Bean是一种规范是一种特殊的java类所以我们先来看看Bean的规范

  • Bean必须生成public class类
  • 所有属性必须封装Bean类的属性都为private
  • 属性值应该通过一组方法(getXxx 和 setXxx)来访问和修改
  • Bean类必须有一个空的构造函数(默认构造函数)

这些就是Bean的基本规范我们可以进行扩充但是这些最基本的都是要满足的否则就算不上一个标准的Bean下面我来举一个标准的Bean的例子注意上面的四个要素

public class User {
    private String id;
    private String name;
    public User(){}
    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

是的Bean就是这样的一种特殊的类这个东西必须要牢记因为后面会经常用到

二、Bean对象的三种构造方式

自从有了spring之后对象的构造不用我们再去操心了一切交给spring完成就行但是框架再高级他的底层依旧是在做一些很简单的事这些事可能我们过去也经常自己来做因此学习spring我们既要知其然也要知其所以然下面我们就来看看有哪些构造Bean对象的方式顺便了解一下他们的原理是什么

1. 构造方法构造

这是我们用的最多的一种构造方式你肯定很好奇在以前的案例中为啥我们在配置文件里面写一句:

<bean id="circle" class="com.demo.Circle"/>

然后这个Bean对象就被spring构造出来放入IOC容器中了?其实这东西没啥高大上的实际上就是spring利用反射调用了这个类的默认构造方法而已就是这么简单

那么问题来了如果我们对象中有属性(暂时假定属性只包含基本类型和String对象属性会在后面讲)我们又该怎么来构造呢?这个配置文件应该怎么去写呢?很简单每个Bean对象中都由setter方法(不记得的可以去复习一下上面写的的Bean的结构)框架可以通过调用setter方法把需要的值传递给属性这就是属性注入比如我们试着构造一个本文开头提到了一个Bean的对象:

<bean id="user" class="com.beans.User">
	<property name="id" value="666"></property>
    <property name="name" value="666"></property>
</bean>

这段配置主要干了什么事呢?首先就像往常一样调用默认构造方法构造出一个对象然后调用两个setter方法分别给两个属性赋值用传统代码表示就是这样:

User user = new User();
user.setId("666");
user.setName("666");

当然平时我们自己很少这么做如果需要给属性赋值我们可以直接重载构造方法通过传参的方式在创建对象的同时直接给属性赋值这样可以减少代码量下面我们来看看怎样让框架调用Bean的有参构造方法:

<bean id="user" class="com.beans.User" >
	<constructor-arg name="id" value="666"></constructor-arg>
    <constructor-arg name="name" value="666"></constructor-arg>
</bean>

这段配置就相当于是直接对有参构造方法进行调用这里的arg是arguement(参数)的缩写所以constructor-arg就是构造方法的参数列表的意思name很显然就是参数名了value就是我们要填入的参数值所以我们就要为参数列表中所有的参数进行填值就像我们过去做的一样:

User user = new User("666", "666");

现在你应该已经了解了spring框架究竟干了什么了吧看似高大上的框架做的事也不过如此嘛最基本的东西是永远逃不掉的

2. 静态工厂构造

这种方式一般只有特定场景会使用所以我们就简单看看就行这里的静态工厂和我们前面讲的工厂模式差不多首先我们要有一个工厂:

public class UserFactory {
    public static User createPerson(){
        return new User();
    }
    public static User createPerson(Integer id,String name){
        return new User(id,name);
    }
}

下面我们来看看配置文件如何书写:

<bean id="user" class="com.beans.factory.UserFactory" factory-method="createPerson">
    <constructor-arg name="id" value="666"></constructor-arg>
    <constructor-arg name="name" value="666"></constructor-arg>
</bean>

使用静态工厂方法创建Bean实例需要为<bean />元素指定除id外如下属性:

  • class:指定静态工厂的全类名(相当于指定工厂的地址)
  • factory-method:指定由静态工厂的哪个方法创建该Bean实例(指定由工厂的哪个车间创建Bean)
  • 方法参数:如果静态工厂方法需要参数则使用<constructor-arg />元素传入

3. 实例工厂构造

实例工厂和静态工厂唯一的区别就是我们需要先实例化工厂对象才能构造我们需要的Bean对象:

<!-- 先构造工厂对象class指定该工厂的实现类工厂对象负责产生其他Bean实例 --> 
<bean id="userFactory" class="com.beans.factory.UserFactory"/> 
<!-- 再引用工厂对象来配置其他Bean -->
<bean id="user" factory-bean="userFactory" factory-method="createPerson">
    <constructor-arg name="id" value="666"></constructor-arg>
	<constructor-arg name="name" value="666"></constructor-arg>
</bean>

调用实例化工厂需要为<bean />指定除id外如下属性:

  • factory-bean :该属性指定工厂Bean的id
  • factory-method:该属性指定实例工厂的工厂方法
  • 方法参数:如果静态工厂方法需要参数则使用<constructor-arg />元素传入

实例工厂和静态工厂平时用的不算特别多平时开发时用的最多的还是最开始说的构造方法构造现在有个重要的问题如果Bean对象的属性是一个对象呢?这就是我们下面要讲的——依赖注入(DI)

三、依赖注入

讲spring IOC不能不讲DI这两个东西基本上可以说是相辅相成、唇亡齿寒的所以现在我们就来看看IOC和DI的关系控制反转——IOC(Inversion of Control)的意思是创建对象的控制权进行转移以前创建对象的主动权和创建时机是由自己把控而现在这种权力转移到了spring

IOC的最重要的一个功能是在系统运行中动态的向某个对象提供它所需要的其他对象作为属性这一点是通过DI(Dependency Injection依赖注入)来实现的下面我来举一个依赖注入的例子:

比如A类需要使用JBDC以前我们要在A类中编写代码来自己new一个Connection对象(这边咱先不考虑数据库连接池)现在有了 spring我们就只需要用配置文件告诉springA类中需要一个Connection对象至于这个Connection怎么构造何时构造A类不需要知道在运行时spring会在适当的时候构造一个Connection对象然后注入到A类当中这样就完成了对各个对象之间关系的控制A类需要依赖Connection这个属性才能正常运行而这个Connection对象是由spring注入到A中的依赖注入的名字就这么来的

看了这么多是不是发现其实依赖注入和我们上文讲的属性注入其实是同一类东西都是动态地给对象的属性赋值只不过这里的属性是一个对象上文讲的的属性是简单类型而已依赖注入听起来很高端实际上就是给对象的对象属性赋值而已

四、Bean的生命周期

讲了如何编写配置文件那么你一定好奇在spring内部每时每刻这个Bean的状态应该是怎么样的于是我们就来看看spring中Bean的生命周期不过有一点要提前说明Spring只帮我们管理单例模式(singleton)Bean的完整生命周期对于 多例模式(prototype)的BeanSpring 在创建好交给使用者之后则不会再管理后续的生命周期了单例模式和多例模式放在后面讲

来看看我们的Bean对象是如何产生的这个图乍一看很吓人其实里面许多东西都是一些扩展点他们穿插于Bean的生命周期中我们一开始不需要去折腾这些扩展点我们的关注点应该在Bean的生命周期本身

其实Bean的生命周期一共只有四个阶段分别是:

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

要彻底搞清楚Spring的生命周期首先要把这四个阶段牢牢记住实例化和属性赋值对应构造方法和setter方法的注入初始化和销毁是用户能自定义扩展的两个阶段我们可以自己在这两个函数里面书写我们需要的逻辑在这四个阶段之间穿插的各种扩展点以后再讲

首先我们先来看前三个他们的主要逻辑都在doCreateBean方法中顺序调用三个方法这三个方法与三个生命周期阶段一一对应:

//PS:下面的代码已经删去暂时不用了解的部分只留下核心部分
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 实例化
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 属性赋值
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

有了这三个再加上一个销毁组成了Bean的最重要的四个生命周期阶段如下图所示当然下图除了这四个基本的生命周期阶段之外还加上了一些扩展点:

在这里插入图片描述

初学时我们只需要知道这些扩展点的存在即可至于他们具体该怎么用后面用到的时候会讲我们在这里需要明白的是四个最基本的生命周期其他的扩展点平时开发很少用到但是在读一些Java中间件源码的时候这些扩展点就必须得弄明白了

Ioc中Bean的作用域

在Spring中可以在< bean >元素的scope属性里设置bean的作用域以决定这个bean是单实例的还是多实例的

默认情况下Spring值为每个在IOC容器里声明的bean创建唯一一个实例整个Ioc容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean该作用域被称为singleton它是所有bean的默认作用域

当bean的作用域为单例时Spring会在IOC容器对象创建时就创建bean的对象实例而当bean的作用域为prototype时Ioc容器在获取bean的实例时创建bean的实例对象

bean的作用范围和生命周期

单例对象: scope=“singleton”

  • 一个应用只有一个对象的实例他的作用范围就是整个引用
  • 生命周期:
  • 对象出生:当应用加载创建容器时对象创建
  • 对象活着:只要容器在对象一直活着
  • 对象死亡:当应用卸载销毁容器时对象销毁

多例对象:scope=“prototype”

  • 每次访问对象时都会重新创建对象实例
  • 生命周期:
  • 对象出生:当使用对象时创建新的对象实例
  • 对象活着:只要对象在使用中就一直活着
  • 对象死亡:当对象长时间不用时就被java的垃圾回收器回收了

以上为个人经验希望能给大家一个参考也希望大家多多支持


相关文章

猜您喜欢

  • C++异常处理 C++的异常处理一篇带你了解

    想了解C++的异常处理一篇带你了解的相关内容吗物随心转在本文为您仔细讲解C++异常处理的相关知识和一些Code实例欢迎阅读和指正我们先划重点:C++,C++异常处理下面大家一起来学习吧..
  • Java Collection 深入浅出讲解Java集合之Collection接口

    想了解深入浅出讲解Java集合之Collection接口的相关内容吗威斯布鲁克.猩猩在本文为您仔细讲解Java Collection的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,Collection,Java,Collection接口下面大家一起来学习吧..

网友评论

Copyright 2020 www.sopisoft.net 【绿软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式