第3章 bean概念

bean概念

§ bean配置

id

bean的id,使用容器可以通过id获取对应的bean,在一个容器中,id唯一

class

bean的类型,即配置的bean的全路径名称

name

bean的别名,多个别名可以用,;或空格分割

在获取bean,或配置中的ref使用时可以使用别名

也必须唯一,否贼会报错

scope

Spring创建的bean默认为单例,使用该属性指定是否单例

  • singleton(默认):单例
  • prototype:非单例
<bean id="bookDao" name="b1" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype" />
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <!-- 配置serve与dao的关系
         property表示配置当前bean的属性
         name表示配置哪一个具体的属性(private Bookdao bookdao)
         ref表示参照哪一个bean配置
         -->
        <property name="bookDao" ref="b1" />
    </bean>

适合交给容器管理的bean

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合

  • 封装实体的对象

§ bean的实例化

调用无参构造方法

Spring通过反射默认调用无参构造方法构造

使用静态工厂

使用静态工厂实例化bean

目的:解决早期的一些使用工厂创建的遗留项目

数据层代码

public interface OrderDao {
    void save();
}
public class OrderDaoImpl implements OrderDao {
    public void save() {
        System.out.println("Order save dao");
    }
}


bean配置

<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao" />

app代码

OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
orderDao.save();

工厂代码

public class OrderDaoFactory {
    public static OrderDao getOrderDao() {
        System.out.println("factory");
        return new OrderDaoImpl();
    }
}

使用实例工厂

<bean id="orderDaoFactory" class="com.itheima.factory.OrderDaoFactory" />
<bean id="orderDao" factory-bean="orderDaoFactory" factory-method="getOrderDao" />

§ FactoryBean

上述使用实例工厂创建了一个工厂的bean,是一个多余的步骤

使用FactoryBean简化工厂创建的步骤

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

    @Override
    public Class<?> getObjectType() {
        return OrderDao.class;
    }
  // 是否是单例,不是直接返回false
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactoryBean" />

§ bean生命周期

  • 生命周期:从创建到消亡的过程
  • bean生命周期:bean从创建到销毁的整个过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

配置方法

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

    // 表示bean初始化对应的操作
    public void init() {
        System.out.println("init dao");
    }

    // 表示bean销毁前对应的操作
    public void destroy() {
        System.out.println("destroy dao");
    }
}

<bean id="bookDao" name="b1" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

打印结果

init

book dao save

可见没有执行destory

要销毁bean,方法如下

  • 手动关闭容器:ApplicationContext换成具体实现类ClassPathXmlApplicationContext后,调用ctx.close()
  • 设置关闭钩子:ApplicationContext换成具体实现类ClassPathXmlApplicationContext后,调用ctx.regusterShutdownHook()

区别:前者必须在不使用bean后调用,后者可以随时调用

这两个关闭操作都来自ClassPathXmlApplicationContext实现的接口ConfigurableApplicationContext

实现接口方法

使用工厂实例化bean无法触发一下的init和destroy

实现接口InitializingBeanDisposableBean

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;
    public void save() {
        System.out.println("book service save");
        bookDao.save();
    }
    // 提供对应的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy service");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("init service");
    }
}
<bean id="bookDao" name="b1" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
	<property name="bookDao" ref="b1" />
</bean>

生命周期

  • 初始化容器
    1. 创建对象(分配内存)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭bean
    1. 执行bean销毁方法

service和dao都实现InitializingBeanDisposableBean接口后执行service.save()结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KflvUApY-1683549857607)(assets/image-20230216185227019.png)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值