Spring Boot手动注入Bean

应用场景

Spring Boot项目中,我们可能遇到@Autowired注入对象为null的问题,可能的原因包含:

(1)当前类的初始化在注入类注入之前
(2)多线程环境,新创建的线程中,是不能自动注入Bean/Service

此时就需要手动注入Bean

手动获取Bean的工具类

原理,在项目启动时获取到Spring Boot上下文,从上下文中获取到Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 接通过Spring 上下文获取SpringBean
* @author yezhou
* @version 1.0
* @date 2019/8/15 18:39
*/
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
// Spring Boot应用上下文环境
private static ApplicationContext applicationContext;

/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
ApplicationContextUtil.applicationContext = applicationContext;
}

public static ApplicationContext getApplicationContext() {
return applicationContext;
}

/**
* 获取对象:这里重写getBean方法,起主要作用
* example: getBean("userService") //注意: 类名首字母一定要小写!
*/
public static Object getBean(String beanId) throws BeansException {
return applicationContext.getBean(beanId);
}
}

在超前初始化类或线程类中手动获取Bean/Service

超前初始化类

1
2
@Component(value = "UserAuthDetailsService")
public class UserAuthDetailsService implements UserDetailsService {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SMSCodeTokenGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "sms_code";

private UserAuthDetailsService authUserDetailsService;

public SMSCodeTokenGranter(AuthorizationServerTokenServices tokenServices,
ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
}

@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client,
TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());
String userMobileNo = parameters.get("username"); //客户端提交的用户名
String smsCode = parameters.get("sms_code"); //客户端提交的验证码

authUserDetailsService = (UserAuthDetailsService) ApplicationContextUtil.getBean("UserAuthDetailsService");
UserDetails user = authUserDetailsService.loadUserByUsername(userMobileNo);

线程类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SdReleaseReview implements Runnable {
    private CalendarService calendarService;

    public SdReleaseReview() {
        this.calendarService=(CalendarService)SpringContextUtil.getBean("calendarService");
    }

    @Override
    public void run() {
        try {
            ...
            FactoryCalendar factoryCalendar = calendarService.getByExistDate("2000", today);
            ...
        } catch (Exception e) {
            ...
        }
    }
}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :