调用new实例化Singleton或@Component修饰类会生成同一对象吗?
嗨,没问题,我来给你掰扯清楚这两个问题~
问题1:两次调用
new A()会得到同一个对象吗? 答案是不会。
虽然A类上标注了@Component,但这个注解的作用只是告诉Spring容器:“这是一个需要你管理的Bean”。但当你直接用new关键字创建对象时,完全绕开了Spring的管理机制——每次new都会在JVM堆内存中开辟新的空间,生成一个全新的实例。
举个直观的代码例子:
A a1 = new A(); A a2 = new A(); System.out.println(a1 == a2); // 输出 false,说明是两个不同的对象
简单说:@Component不影响你手动new对象的行为,手动new永远会生成新实例。
问题2:如果Bean是Singleton(单例),调用
new Bean()会出现什么情况? 首先要明确:Spring的“单例”是容器范围内的单例——只有当你通过Spring容器获取Bean(比如ApplicationContext.getBean()、依赖注入)时,Spring才会保证每次拿到的是同一个实例。
而你手动调用new Bean()时,会发生这些事:
- 你创建的这个对象完全不受Spring容器管理,Spring根本不知道它的存在
- 哪怕Spring已经在容器中维护了一个该类的单例实例,你
new出来的是另一个全新的独立实例,和Spring的单例Bean没有任何关联 - 如果你的Bean类里有Spring注入的依赖(比如
@Autowired的字段),那你new出来的对象中这些依赖都是null——因为Spring没机会为这个手动创建的实例完成注入流程
举个场景示例:
// 标注为Spring单例Bean(默认就是单例) @Component public class MySingletonBean {} // 调用逻辑 public class Demo { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // 从Spring容器获取的单例实例 MySingletonBean springManagedBean = context.getBean(MySingletonBean.class); // 手动new的全新实例 MySingletonBean manuallyCreatedBean = new MySingletonBean(); // 输出false,说明是两个不同的对象 System.out.println(springManagedBean == manuallyCreatedBean); } }
总结一下:Spring的单例约束只对容器管理的实例生效,手动new完全不受这个规则限制,会生成独立于容器的新实例。
内容的提问来源于stack exchange,提问作者Paras Meena
相关产品推荐
相关产品推荐

