IOC容器——Bean

Bean配置

bean图

name别名属性

Bean ID 唯一,而关于Spring别名,我们可以在配置文件中使用name来定义,解决命名时产生的分歧在这里插入图片描述

注意哦“class”属性不能写接口如BookDao的类全名,因为接口是没办法创建对象的。

  • NoSuchBeanDefinitionException:
    这个异常可能是我们经常遇到的异常,需要特别注意哦,主要是因为无法获取到IOC中的Bean(不管是通过name还是id无法获取时都会抛出这个异常)

🍊个🌰:
很明显没有service2这个别名
示例别名

诺就会爆下面这个错误咯:
诺出现错误咯

Bean作用范围scope

先看一个图
默认单例
很明显我们可以看出Spring为我们创建对象时是单例的,即只创建一个相同的对象,即scope=“singleton” 如果我们把属性切换为scope=“prototype”,便不再是单例。
scope
结果

那么为什么Spring管理的对象默认是单例的嘞,其实很容易想,如果不是单例的话,那就会创建无穷多个咯,bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,提高性能,所以IOC也更适合管理可复用的一些对象。比如:表现层对象 业务层对象 数据层对象 工具对象(更适合交给IOC管理);相反封装实例的域对象(实体类),因为会引发线程安全问题,所以不适合。

  • 关于单例Bean的一些线程安全问题
    如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,因为所有请求线程共用一个bean对象,所以会存在线程安全问题。如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。

因为是单例的所以我们创建的类对象都是同一个类,如果我们根据这个bean创建了多个不同的类并且需要修改时,修改一个其他都会改变

Bean的实例化

通过前面的学习我们大概已经知道了,IOC如何管理对象,那么IOC中的对象又是如何进行创建的捏?

首先关于如何示例话bean,我们有三种方式:构造方法、静态工厂、实例工厂

构造方法示例化

首先我们做好一些准备
1、配置好Spring环境后,准备一个BookDao接口和BookDaoImpl类

public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

book类准备

2、既然我们说了是使用构造方法进行实例化那么何以见得捏
我们给它加一个构造方法观察它是否执行构造方法就好啦

public class BookDaoImpl implements BookDao {
    
    public BookDaoImpl() {
        System.out.println("book dao constructor is running ....");
    }

    public void save() {
        System.out.println("book dao save ...");
    }

}

构造方法

甚至我们可以尝试把public修饰换成private,我们发现同样可以(暴力反射我们日后再提),如果我们再在构造方法加入参数我们会发现无法运行,经过尝试我们便可知道Spring创建Bean使用的是无参构造方法

静态工厂实例化

我们创建一个静态工厂并配置一下xml文件。
在这里插入图片描述

同时我们对他编写启动类进行启动测试
静态工厂启动累

当然我们工厂类创造时一定要注意那个具体的实例方法即factory-method

实例工厂与FactoryBean

实例工厂

我们发现实例工厂与静态工厂及其相似不同点的话就是静态工厂中的方法是静态方法。

所以我们在修改配置文件时也要注意实例工厂造Bean时首先要把实例工厂这个Bean造出来
实例工厂配置方法
模型图

所以我们会发现userFactory被创建出来就是为了创造底下的bean,我们有什么办法再进行一下优化吗?——FactoryBean

FactoryBean

还是上面的实例工厂但是我们在创建实例工厂的时候,让这个Bean实现FactoryBean这个接口,同时他的范型为我们需要造的对象。

当然我们需要实现他的方法,默认会实现两个如下图所示
实现方法

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //代替原始实例工厂中创建对象的方法
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    public Class<?> getObjectType() {
        return UserDao.class;//要注意这里的类型
    }

}

当然配置文件也要改咯
factory
当然此时我们的创建对像依旧默认是单例的,如果我们在实例工厂时,多实现一个方法便可使其非单例,(当然配置文件也可当如果同时使用scope,则以下面这个方法为主)如下图所示:

是否单例

bean的生命周期

通过添加init-method=“” 与destroy-method=""属性来控制初始化与关闭
值得注意的是Spring的IOC容器是运行在JVM中运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了所以没有调用对应的destroy方法,那如果我们需要关闭容器呢?因为ApplicationContext中没有close方法需要将ApplicationContext更换成ClassPathXmlApplicationContext便可在最后添加close执行关闭程序的方法内容。

当然close是暴力关闭,我们还可以注册关闭钩子

ctx.registerShutdownHook() :任何地方都可以在运行完后关闭钩子。

(意思就是close关闭属于暴力关闭后无法执行后面内容)

其实以上内容我们相对用的都较少,所以我们并没有加图片示意或者标注

我们更推荐service实现相应的接口与方法
实现接口与方法

当然顾名思义afterPropertiesSet方法会在类属性设置执行之后再执行

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一哑7

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

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

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

打赏作者

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

抵扣说明:

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

余额充值