Spring Bean 懒加载初始化

9
我在思考Spring中bean的延迟初始化。对我来说,“lazy”在这里的含义不是很清晰,具体指的是当一个bean被引用时才会被创建。
我原本认为,Spring中提供的延迟初始化支持与上述情况不同。我认为这应该是一种“方法调用”式的延迟创建。我的意思是,只要在该方法上调用任何方法,它将会被创建。
我认为,通过创建特定bean的代理实例并在任何方法调用上进行初始化,这个问题可以很容易地解决。
我是否漏掉了什么导致这个功能没有被实现?这个概念有什么问题吗?
欢迎提供任何反馈/想法/答案。
2个回答

5
您可以通过使用proxyModeScopedProxyMode.TARGET_CLASS(CGLIB)或ScopedProxyMode.INTERFACES(JDK)来限定您的bean,以达到所需的行为。

例如:

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

展示了在Spring上下文中注入的Foo实例中调用方法后,Foo bean 仅通过其@Bean工厂方法进行了初始化。 @Scope注解也可以在类声明中使用。

你知道如何像这样实现Bean的懒加载吗?“return FactoryProvider().getFactory()” - Fisk

-1
以下是我的观点:
Spring容器中的Bean类型有两种作用域。一种是Prototype,这种类型的Bean不会存在lazy-init概念,因为每次客户端调用getBean()方法时都会实例化这些Bean。另一种是Singleton,这些Bean将被实例化一次,如果您使用@Lazy或lazy-init=true定义Bean,则可以延迟实例化(只有在使用时才实例化,例如@Autowired、refrenced)。
如何实现lazy-init:
是的,常见的实现方式是代理模式。Spring使用JDK动态代理和Cglib来实现代理,您可以进一步了解这些技术。
希望能对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接