简体   繁体   English

Spring bean 延迟初始化

[英]Spring bean lazy initialization

I was thinking about the lazy-initialization of beans in Spring.我在考虑 Spring 中 bean 的延迟初始化。 For me, it wasn't crystal clear that the "lazy" here means that a bean will be created when it's referenced.对我来说,这里的“懒惰”意味着在引用 bean 时将创建 bean,这一点并不十分清楚。

I expected that the lazy initialization support in Spring is different.我预计 Spring 中的延迟初始化支持是不同的。 I thought this is a "method-call" based lazy creation.我认为这是基于“方法调用”的懒惰创建。 What I mean by this is, whenever any method is being called on the method, it will be created.我的意思是,每当在该方法上调用任何方法时,都会创建它。

I think this could be easily solved by creating a proxy instance of the specific bean and do the initialization on any method call.我认为这可以通过创建特定 bean 的代理实例并在任何方法调用上进行初始化来轻松解决。

Am I missing something why this is not implemented?我是否错过了为什么没有实施的原因? Is there any problem with this concept?这个概念有问题吗?

Any feedback/idea/answer will be appreciated.任何反馈/想法/答案将不胜感激。

You can achieve the behavior you want by scoping your bean with a proxyMode of ScopedProxyMode.TARGET_CLASS (CGLIB) or ScopedProxyMode.INTERFACES (JDK).您可以通过实现与一个范围的豆你想要的行为proxyModeScopedProxyMode.TARGET_CLASS (CGLIB)或ScopedProxyMode.INTERFACES (JDK)。

For example例如

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 {
}

will print将打印

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

demonstrating that the Foo bean was initialized through its @Bean factory method only after a method was invoked on the Foo instance injected by the Spring context in the Bar bean.证明只有在Bar bean 中的 Spring 上下文注入的Foo实例上调用了一个方法之后, Foo bean 才通过其@Bean工厂方法进行初始化。

The @Scope annotation can be used in a class declaration as well. @Scope注解也可以在类声明中使用。

bellow is my views:以下是我的观点:

Bean types in Spring Container: Spring Container 中的 Bean 类型:

There are two Scope bean type in Spring Container .One is Prototype , this type bean won't exist lazy-init concept, because these beans will be instantiated when clients invoke the getBean() method every time . Spring Container中有两种Scope bean类型,一种是Prototype ,这种类型的bean不存在lazy-init的概念,因为客户端每次调用getBean()方法都会实例化这些bean。 Another is Singleton , these bean will be instantiated once , these beans can be lazily instantiated( just be instantiated when they're used, such as @Autowired, refrenced) if you define the bean use @Lazy or lazy-init=true .另一个是Singleton ,这些 bean 将被实例化一次,如果使用@Lazylazy-init=true定义 bean,则这些 bean 可以延迟实例化(只需在使用时实例化,例如 @Autowired、 refrenced)

How to implement lazy-init :如何实现惰性初始化

Yes, common implementation is Proxy Mode .是的,常见的实现是Proxy Mode Spring use JDK Dynamic Proxy and Cglib to implement Proxy , you can go further understanding about these techs. Spring 使用JDK Dynamic ProxyCglib来实现Proxy ,您可以进一步了解这些技术。

Hope to help you.希望能帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM