Spring 中如何通过 Autowired 往 Java 枚举中注入 Service 依赖?

假设我们的 Springboot 有一个 Service 类:

package com.test.service;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void print(String text) {
        System.out.println(text);
    }
}

以及一个Strategy枚举类,它会引用 UserService 里面的 print 方法,如下:

package com.test.enumeration;
import org.springframework.beans.factory.annotation.Autowired;

public enum Strategy {
    CHINESE("这是中文"),
    ENGLISH("This is English"),

    private final String text;
    
    @Autowired
    private UserService userService;

    Strategy(String text) {
        this.text = text;
    }

    public void printText() {
        userService.print(text);
    }
}

这样写运行的时候会报NullPointerException错误,因为 @Autowired 只能用在有效 Spring Bean 里面,包括Bean、Service、Component等,而 enum 却不是 Bean,所以 Service 对象不会自动注入进来。

解决办法就是:增加一个内部类,让它在 Springboot 启动的时候就往枚举中注入。

package com.test.enumeration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.EnumSet;

public enum Strategy {
    CHINESE("这是中文"),
    ENGLISH("This is English"),

    private final String text;
    private UserService userService;

    Strategy(String text) {
        this.text = text;
    }

    public void printText() {
        userService.print(text);
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Component
    public static class SetUserService {
        // 因为这个类是个 Component,所以 Springboot 启动的时候会自动注入依赖
        @Autowired
        private UserService userService;

        @PostConstruct
        public void setUserService() {
            for (Strategy strategy: EnumSet.allOf(Strategy.class)) {
                strategy.setUserService(userService);
            }
        }
    }
}

下面是测试代码:

package com.test.enumeration;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import static com.test.enumeration.Strategy.*;

@SpringBootTest
class StrategyTest {
    @Test
    void printText() {
        CHINESE.printText();
        ENGLISH.printText();
    }
}

打印结果:

这是中文
This is English

参考:Inject bean into enum


已有 0 条评论

    感谢参与互动!