关于registerSingleton()方法的缺点

之前在《如何把对象放入spring容器》这篇文章中,提到了registerSingleton()方法。说这个方法有些鸡肋。

利用这篇文章解释一下为什么说这个方法它比较鸡肋呢。

注:读这篇文章前需要你对spring的依赖关系有一定的了解,否则可能看起来吃力一些。

如果实在看不懂,就记住用法就行了,不用纠结。

 一、关于存在的问题

/**
 * 按照这种写法的话,
 * 因为当前要托管给spring容器的对象是我新new出来的,名称为EvanService,
 * 依赖EvanService的对象 名称为PersonService。EvanService依赖的对象 名称为TomService。
 * 这就存在两个问题:
 * 1.如果Spring管理的PersonService,依赖对象EvanService,在所有对象完成实例化后,你才将EvanService托管给spring容器,此时是没有作用的。
 * 因为你需要在所有对象实例化之前,就将EvanService托管给spring。这样依赖EvanService的 PersonService对象才能完成实例化。
 * 2.如果EvanService对象,依赖TomService对象。你需要做的是先把EvanService对象先托管给spring容器,然后从spring容器中获取EvanService对象。
 * 但是因为此时这种写法,你是自己new的(此时并没有处理EvanService和TomService的依赖关系),然后才交给spring,这样也是没有任何意义的。
 */

二、问题1.代码证明

//你可以把EvanService当成是与第三方应用交互产生的对象。
public class EvanService {
}

 

@Component
public class PersonService {
    @Autowired
    EvanService evanService;

    public void showEvanServiceResult() {
        System.out.println(evanService);
    }
}

 错误示范:(注意这样是错误的) 对应问题1.

public class TestFirst {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        EvanService evanService = new EvanService();
        ac.getBeanFactory().registerSingleton("evanService",evanService);
        ac.getBean(PersonService.class).showEvanServiceResult();
    }
}

正确写法: 

/**
 * 按照这种写法的话,
 * 这样的写法我们就解决了部分问题,什么问题呢?解决了现有类依赖新对象的问题。
 * 这样写的话,是先将我们的EvanService托管给spring容器,也就是注入到spring容器中,这样的话,然后再进行bean的实例化,
 * 这样的PersonService此时依赖的EvanService就已经是被spring容器管理的bean了。所以能够正常打印。
 *
 * 但是这样写还是有问题,问题就是如果我们的新类,还需要依赖现有类怎么办?
 * 通俗的讲就是如果EvanService需要依赖 TomService,在EvanService中@Autowired TomService。
 * 因为此时的EvanService是new出来的(实际有可能是第三方交互产生),所以肯定没法处理与TomService的依赖关系。
 * 所以还是没办法解决,这就是registerSingleton()这个方法鸡肋的地方。
 * 请看   三、问题2.代码证明
 */
public class TestSecond {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        EvanService evanService = new EvanService();
        ac.getBeanFactory().registerSingleton("evanService",evanService);
        //将扫描到的类注册到spring容器
        ac.register(AppConfig.class);
        //刷新容器,完成bean的实例化
        ac.refresh();
        ac.getBean(PersonService.class).showEvanServiceResult();
    }
}

运行结果:

com.evan.service.EvanService@7ae42ce3

 

三、问题2.代码证明 

 

package com.evan.service;

public class TomService {
}
package com.evan.service;

import org.springframework.beans.factory.annotation.Autowired;

//你可以把EvanService当成是与第三方应用交互产生的对象。
public class EvanService {
    @Autowired
    TomService tomService;

    public TomService showTomServiceResult() {
        return tomService;
    }
}

 

package com.evan.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PersonService {
    @Autowired
    EvanService evanService;

    public void showEvanServiceResult() {
        System.out.println(evanService);
        System.out.println(evanService.showTomServiceResult());
    }
}
public class TestSecond {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        EvanService evanService = new EvanService();
        ac.getBeanFactory().registerSingleton("evanService",evanService);
        //将扫描到的类注册到spring容器
        ac.register(AppConfig.class);
        //刷新容器,完成bean的实例化
        ac.refresh();
        ac.getBean(PersonService.class).showEvanServiceResult();
    }
}

运行结果: 

//TomService打印结果为null,证明我们问题2.的存在。
com.evan.service.EvanService@7ae42ce3
null

四、结论

TomService打印结果为null,证明我们问题2.的存在。因为类似EvanService这种与第三方交互产生的对象或者new出来的对象,总是新产生的所以我们无法控制。所以说这个方法有些鸡肋。

 

 

 

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Evan Wang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值