有关Spring中对象的生命周期

几种方式创建对象

  • 简单对象

    • 直接new创建对象()---> 基于反射完成

  • 复杂对象

    • 不能被直接new创建对象

    • 接口类型的创建,不可以直接new,通过实现类来创建,这些实现类也不能直接被new出来的

    • 比如Connection。

    • 所以这些对象使用FactoryBean创建方式(实现FactoryBean接口)

    • getObject(),getObjectType(),isSinglenton

    • 也可以根据静态工厂,实例工厂,他们俩不需要实现接口,静态工厂在xml里指定<bean factory-method,而实例工厂的方法没有static修饰,无法通过类名.创建,所有要先创建对象再使用,因此应该在XML文件中先配置实例工厂的对象,再<bean id="" factory-bean="工厂的beanName" factory-method="创建的对象的方法"

 但是如果仅此而已的话,对于Spring来说可能就有点无用了,因为仅仅这样的话,我们得到的也就是一个简单的对象,我们还要考虑为对象的属性赋值,即注入。

注入分为几种方式:

  • set注入(最常用)程序员完成的注入(八种基本类型(value,list),自建类型注入(ref-bean)),容器自己的注入--> Aware

  • 对象的beanName命名是在xml里的,怎么在对象内部获得beanName,通过这个对象实现BeanNameAware接口实现,那么下面这个set就是负责Spring调用执行的

  • 那么同时,我想在我对象里使用当前的Bean工厂怎么办?

    • 如果我们直接在对象中直接new一个工厂,我们想要获得的是当前加工bean的工厂,如果我们新new一个工厂,就相当于有两个工厂,Spring工厂是重量级资源,一种类型的工厂,我们只创建一个,同时实现BeanFactoryAware接口的方法,Spring通过调用这个方法将工厂传递给当前对象。

  • public class Account implements BeanNameAware, BeanFactoryAware {
        private String name;
        private String password;
    
        private String beanName;
        private BeanFactory beanFactory;
    
        @Override
        public void setBeanName(String name) {
            this.beanName = name;
        }
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("Account.setBeanFactory");
            this.beanFactory = beanFactory;
        }
    }

    • 不会发生重载 - Spring内部也是使用的set

    • 可以避免循环引用。

  • 构造注入

  • autowire 自动注入

在完成对象的创建和注入之后,Spring允许我们执行一个方法,来完成对对象的初始化,即执行初始化方法,定义的方式有两种

第一种,在对象内部随意顶一个方法,并在其中书写初始化方法。

 但此时,Spring并不会知道这个方法就是这个对象的初始化方法,因此我们应该在xml文件中来告知Spring。

 第二种方法,实现Spring规定的接口

并实现该接口的方法,其中书写要执行的初始化方法,不需要在xml文件中告知Spring容器,两种方法同时存在,优先执行第二种,Spring一般都会有限执行实现了他的接口的,此时,我们创建的这个对象基本上就可以被使用了。

当对象使用结束,应该对对象执行销毁操作,同样有两种方式完成,我们可以在类中定义一个销毁方法,任意名字,其中书写对象被销毁之前,要执行什么操作(释放资源的操作),比如IO流的关闭,比如把一些对象的引用置为null。

 同样,我们也要告知Spring,这个对象的销毁方法是什么。

 第二种,也可以去实现接口,去实现Disposablebean的接口

注意:单例对象的销毁是在Spring工厂关闭的时候执行的。

虽然,上述步骤已经可以保证用户使用对象了,但Spring还提供了BeanPostProcessor方法,来让用户可以对对象进一步的加工处理。

那这一步是不是有一些多余,为什么我不在定义对象的过程中我直接增加功能,我还要多此一举,在后置处理bean的时候在执行一次加工呢?

但注意,我们并不是只有一个对象,那么如果我想要给10个对象同时增加一个功能,比如登录验证,那么Spring工厂就可以通过BeanPostProcess来完成对所有对象的功能增加,避免了我要给10个对象附加相同的功能,避免了代码冗余,另一方面,我们附加的功能都不是这个对象要完成的主要的功能,只是次要的功能,也在一定程度上实现了解耦合。

要让Spring执行后置处理Bean,需要创建一个类并实现BeanPostProcessor接口。

before在注入之后,初始化之前被触发,after在初始化之后被触发

入参中的bean就是要被加工的对象,beanName就是id值(一般情况下,前文源码有述),返回值是被加工后的bean

同时告知Spring

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值