2、bean

文章详细介绍了Spring框架中Bean的配置,包括设置别名、修改单例模式,以及通过不同方式实例化Bean。还探讨了Bean的生命周期,如初始化方法、销毁方法的执行,并提到了ApplicationContext在关闭时如何触发销毁操作。最后,文章提到了通过实现接口来管理Bean的生命周期,以及Bean底层实现的反射机制。
摘要由CSDN通过智能技术生成

bean的别名配置:

在bean内,还有一个属性叫name,可以为bean起别名,里面的别名可以是多个,可以用空格、逗号、分号分开,如下:

<bean id="bookDao" name="bookDao2 bookDao3,bookDao4;bookDao5" class="dao.impl.BookDaoImpl"/>

起别名后,getBean("")方法和ref里面都可以用别名。

bean的单例模式修改:

在bean内,还有一个属性叫scope,其参数列表有两个,一个是"singleton",表示单例模式,一个是"prototype",表示多例模式。bean默认下为单例模式,因为其本身存在的意义就是存放和管理可以复用的对象。

 测试单例和多例:

public class App2 {
    public static void main(String[] args) {
//        获取IoC容器,参数是自己配置的applicationContext.xml文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//        通过getBean方法获取bean,参数是在bean中设置的id名字
        BookService bookService1 = (BookService) ac.getBean("service2");
        System.out.println(bookService1);;
        BookService bookService2 = (BookService) ac.getBean("service2");
        System.out.println(bookService2);
    }
}

左多例,右单例。

实例化bean:

通过构造方法:

<bean id="bookDao" name="Dao" class="dao.impl.BookDaoImpl"/>

通过静态工厂(了解即可):

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

通过实例工厂(了解即可):

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

通过工厂bean(重要,是实例工厂的进阶):

package factory;

import org.springframework.beans.factory.FactoryBean;
import service.BookService;
import service.Impl.BookServiceImpl;

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

    @Override
    public Class<?> getObjectType() {
        return BookService.class;//返回什么类型,即这个工厂要创建什么类型的对象
    }

    @Override
    public boolean isSingleton() {
        return true;//单例模式为true 非单例模式为false,默认为单例模式
    }
}
<bean id="bookService" class="factory.BookServiceFactoryBean"></bean>
注意:不适用于BookServer这种和其他类对象有关联,需要依赖注入的,会报错NullPointerException。

bean的生命周期:

package dao.impl;

import dao.BookDao;

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

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

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

}
<bean id="bookDao" class="dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

运行后发现,没有book dao destroy,即没有执行析构函数。

要想让bean析构,我们需要把ApplicationContext换成其子类ClassPathXmlApplicationContext才能调用后者的特有方法close。

import dao.BookDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext
        ("applicationContext.xml");
        BookDao bookDao =(BookDao) ac.getBean("bookDao");
        bookDao.save();
        ac.close();
    }
}

或者是注册关闭钩子,其可以放在任何地方,最后一行也可以。

import dao.BookDao;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext
        ("applicationContext.xml");
        ac.registerShutdownHook();
        BookDao bookDao =(BookDao) ac.getBean("bookDao");
        bookDao.save();
        ac.close();
    }
}

两者对比就是close更暴力些,不过项目开发中另有方法关闭,不用的这两个。

升级版本:

直接在bean要创建的对象的类中实现两个接口InitializingBean, DisposableBean,然后重写接口中的方法destroy和afterPropertiesSet即可,bean中不需要再额外写init-method="" destroy-method=""了。

package dao.impl;

import dao.BookDao;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

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

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

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("system init");
    }
}

bean底层实现:

bean底层用的是暴力反射破解要创建的对象的类,调用后者的无参构造方法,所以哪怕后者的构造方法设置成私有,也可以调用。但是如果后者只有有参构造方法,则会报错。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鸡鸭扣

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

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

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

打赏作者

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

抵扣说明:

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

余额充值