当前位置: 首页 > 知识库问答 >
问题:

Spring bean懒惰初始化

乜承嗣
2023-03-14

我在想Spring中bean的懒惰初始化。对我来说,这里的“懒惰”是否意味着当一个bean被引用时会被创建并不十分清楚。

我认为Spring中的延迟初始化支持是不同的。我认为这是一个基于“方法调用”的惰性创建。我的意思是,每当对该方法调用任何方法时,都会创建该方法。

我认为这可以通过创建特定bean的代理实例并对任何方法调用进行初始化来轻松解决。

我是否遗漏了一些东西?为什么没有实施?这个概念有什么问题吗?

如有任何反馈/想法/答案,将不胜感激。

共有2个答案

呼延修然
2023-03-14

以下是我的观点:

Spring容器中的Bean类型:

Spring容器中有两种作用域bean类型。一个是Prototype,这种类型的bean不存在lazy init概念,因为每次客户端调用getBean()方法时,这些bean都会被实例化。另一个是Singleton,这些bean将被实例化一次,如果您定义bean use@Lazy或Lazy init=true,那么这些bean可以被延迟实例化(仅在使用它们时实例化,例如@Autowired,referenced)。

如何实现lazy init:

是的,常见的实现是代理模式。Spring使用JDK动态代理和Cglib实现代理,您可以进一步了解这些技术。

希望能帮助你。

谭刚毅
2023-03-14

通过使用ScopedProxyMode的proxyMode来限定bean的范围,可以实现所需的行为。目标类(CGLIB)或范围模式。接口(JDK)。

例如

public class StackOverflow {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Conf.class);
        Bar bar = ctx.getBean(Bar.class);
        System.out.println(bar);
        System.out.println(bar.foo.toString());
    }
}

@Configuration
class Conf {
    @Bean
    @Lazy
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Foo foo() {
        System.out.println("heyy");
        return new Foo();
    }

    @Bean
    public Bar bar() {
        return new Bar();
    }
}

class Bar {
    @Autowired
    public Foo foo;
}

class Foo {
}

将打印

com.example.Bar@3a52dba3
heyy
com.example.Foo@7bedc48a

证明只有在bean中的Spring上下文注入的Foo实例上调用了一个方法之后,Foobean才通过其@bean工厂方法初始化。

@Scope注释也可以用于类声明中。

 类似资料:
  • 问题内容: 创建单例的模式似乎是这样的: 但是我的问题是,如果Singleton构造函数执行的不是单元测试友好的操作,例如如何调用外部服务,jndi查找等,您如何使用这样的类进行单元化? 我想我可以像这样重构它: 现在的问题是,仅出于单元可测试性,我已强制将getInstance同步,因此仅出于测试方面,它将对实际应用程序产生负面影响。有没有解决的办法,由于Java中双重锁定模式的破坏性,似乎其他

  • 在某些情况下,我的广播接收器是不需要的,所以需要检查接收器是否为空,但有些如何这个对象不为空,即使不使用它和造成崩溃。

  • 你知道为什么jackson不能将这个集合映射到json格式吗?

  • 问题内容: 我有一个初始化为的变量: 问题是,在某个时候,我需要重置此变量,以便在更改后可以再次初始化。但是如果我将类设置为可选的话,LLVM在尝试将它设置为时会给我一个错误。如果我只是使用将其重置在代码中的某个位置,它将最终显示为。 有没有一种方法可以使用并允许自己重置? 问题答案: 懒惰是明确的仅一次初始化。您要采用的模型可能只是按需初始化模型: 现在,只要是,它会被初始化并返回。可以通过设置

  • 问题内容: 当我尝试获取懒惰的初始化实体时,我在IDE中看到以下异常消息(我无法找到它在代理实体中的存储位置,因此无法为该异常提供整个堆栈跟踪): 这是我尝试访问要使用的惰性初始化实体的字段后得到的堆栈跟踪: 我正在使用Spring Data,已配置JpaTransactionManager,数据库是MySql,ORM提供程序是Hibernate4。注释@EnableTransactionMana

  • 我有一个应用程序(Spring 4 MVC Hibernate 4 MySQL Maven集成示例使用注释),使用基于注释的配置将Spring与Hibernate集成。 我有这个实体: 和这个: 服务中的这种方法: 在控制器中: 但我得到了这个错误: