Why lazy loading?

The @lazy annotation is needed to reduce the time it takes to instantiate objects to the IOC container when a SpringBoot application is started

When an object is added to the container

The following code

package com.startdusk.forgot.service;

import org.springframework.stereotype.Component;

@Service
public class LazyService {
    public LazyService(a) {
        System.out.println("LazyService add to ioc container");
    }

    public void print(a) {
        System.out.println("lazy"); }}Copy the code

Since we annotated the @service annotation in LazyService, the LazyService will be instantiated immediately when the program starts. We wrote a constructor in LazyService with no arguments to test it. The startup program will print

So, with the @service annotation, the instantiation object is added to the container as soon as the program starts

Use @lazy to lazily join containers

Let’s rewrite the code to delay adding to the container:

package com.startdusk.forgot.service;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

@Service
@Lazy
public class LazyService {
    public LazyService(a) {
        System.out.println("LazyService add to ioc container");
    }

    public void print(a) {
        System.out.println("lazy"); }}Copy the code

Let’s run the program again:

LazyService added to IOC Container is not instantiated. This indicates that the @lazy annotation is in effect, delaying the object’s addition to the container

A strange phenomenon

So in the real case, we would call the service in the Controller, that is, inject this object into the Controller:

package com.startdusk.forgot.api.v1;

import com.startdusk.forgot.service.LazyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/v1/lazy")
public class LazyController {

    @Autowired
    private LazyService lazyService;

    @GetMapping("/test")
    public String test(a) {
        lazyService.print();
        return "Hello, world"; }}Copy the code

Keeping @Lazy in LazyService, we run the program

To solve this problem, we also need to annotate LazyController with @lazy to delay joining the IOC container

package com.startdusk.forgot.api.v1;

import com.startdusk.forgot.service.LazyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/v1/lazy")
@Lazy
public class LazyController {

    @Autowired
    private LazyService lazyService;

    @GetMapping("/test")
    public String test(a) {
        lazyService.print();
        return "Hello, world"; }}Copy the code

How long will @lazy be delayed

Is delayed until the object is called. Such as to run the program, access localhost: 8080 / v1 / lazy/test is access to test this method, you will call lazyService. Print () will print out:

As you can see, when the injected object is called, the object is added to the IOC container and then injected

Disadvantages of using @lazy

Let’s adjust the code: LazyService comments out @service and @lazy

package com.startdusk.forgot.service;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

// @Service
// @Lazy
public class LazyService {
    public LazyService(a) {
        System.out.println("LazyService add to ioc container");
    }

    public void print(a) {
        System.out.println("lazy"); }}Copy the code

Then run the code, and then to access the localhost: 8080 / v1 / lazy/test, so, the program will give us throw an error:

Error creating bean with name 'lazyController': Unsatisfied dependency expressed through field 'lazyService'; .Copy the code

I just can’t find this object this injected object. This error is reported during program execution, not when the program is started. So let’s get rid of @Lazy in LazyController

package com.startdusk.forgot.api.v1;

import com.startdusk.forgot.service.LazyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/v1/lazy")
public class LazyController {

    @Autowired
    private LazyService lazyService;

    @GetMapping("/test")
    public String test(a) {
        lazyService.print();
        return "Hello, world"; }}Copy the code

Start the program, and it will immediately report an error when the program starts, and won’t let you run it

Field lazyService in com.startdusk.forgot.api.v1.LazyController required a bean of type 'com.startdusk.forgot.service.LazyService' that could not be found.

Copy the code