@Lazyโ
Indicates whether a bean is to be lazily initialized.
By default, Clawject creates all singleton beans eagerly when all configuration classes are instantiated. However, there are cases when we need to create a bean, not at the context initialization, but only when the consumer of the bean needs it.
Be careful when @Lazy
is applied to async beans with custom scope (e.g. request
),
it may cause that promise will be injected instead of actual value.
Bean
level annotations have precedence over class level annotations.@Lazy
can be applied to@Configuration
class or to the bean declaration.@Lazy
decorator accepts optional boolean parameter that indicates is target will be lazy or not, so to make it eager, you can use@Lazy(false)
.
Lazy on @Configuration
classโ
When we put @Lazy
decorator on the @Configuration
class,
it indicates that all the beans that are declared in configuration should be loaded lazily.
Let's have a look here:
import {Bean, ClawjectApplication, ClawjectFactory, ExposeBeans, Lazy, PostConstruct} from '@clawject/di';
class Foo {
@PostConstruct
postConstruct() {
console.log('Foo bean has been created');
}
}
class Bar {
@PostConstruct
postConstruct() {
console.log('Bar bean has been created');
}
}
@ClawjectApplication
@Lazy
class Application {
foo = Bean(Foo);
bar = Bean(Bar);
exposed = ExposeBeans<{ foo: Foo, bar: Bar }>();
}
const applicationContext = await ClawjectFactory.createApplicationContext(Application);
const foo = await applicationContext.getExposedBean('foo');
// logs: Foo bean has been created
const bar = await applicationContext.getExposedBean('bar');
// logs: Bar bean has been created
As we see, all beans are created only when we request them for the first time.
Lazy on Beansโ
We can also put @Lazy
decorator over the bean declaration.
import { Bean, ClawjectApplication, ClawjectFactory, ExposeBeans, Lazy, PostConstruct } from '@clawject/di';
class Foo {
@PostConstruct
postConstruct() {
console.log('Foo bean has been created');
}
}
@ClawjectApplication
class Application {
@Lazy foo = Bean(Foo);
exposed = ExposeBeans<{ foo: Foo }>();
}
const applicationContext = await ClawjectFactory.createApplicationContext(Application);
await applicationContext.getExposedBean('foo');
// logs: Foo bean has been created
Combining @Lazy on @Configuration and Beanโ
You can safely combine @Lazy
on @Configuration
and on the bean level.
import { Bean, ClawjectApplication, ClawjectFactory, ExposeBeans, Lazy, PostConstruct } from '@clawject/di';
class Foo {
@PostConstruct
postConstruct() {
console.log('Foo bean has been created');
}
}
class Bar {
@PostConstruct
postConstruct() {
console.log('Bar bean has been created');
}
}
@ClawjectApplication
@Lazy
class Application {
@Lazy(false) foo = Bean(Foo);
bar = Bean(Bar);
exposed = ExposeBeans<{ bar: Bar }>();
}
const applicationContext = await ClawjectFactory.createApplicationContext(Application);
// logs: Foo bean has been created
await applicationContext.getExposedBean('bar');
// logs: Foo bean has been created