autowired用在static_想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做...

生命太短暂,不要去做一些根本没有人想要的东西。本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈、MyBatis、JVM、中间件等小而美的专栏供以免费学习。关注公众号【BAT的乌托邦】逐个击破,深入掌握,拒绝浅尝辄止。

c7d0f977ebade8680ac4c20ea98c3fb2.png

前言

各位小伙伴大家好,我是A哥。通过本专栏前两篇的学习,相信你对static关键字在Spring/Spring Boot里的应用有了全新的认识,能够解释工作中遇到的大多数问题/疑问了。本文继续来聊聊static关键字更为常见的一种case:使用@Autowired依赖注入静态成员(属性)。

在Java中,针对static静态成员,我们有一些最基本的常识:静态变量(成员)它是属于类的,而非属于实例对象的属性;同样的静态方法也是属于类的,普通方法(实例方法)才属于对象。而Spring容器管理的都是实例对象,包括它的@Autowired依赖注入的均是容器内的对象实例,所以对于static成员是不能直接使用@Autowired注入的。

这很容易理解:类成员的初始化较早,并不需要依赖实例的创建,所以这个时候Spring容器可能都还没“出生”,谈何依赖注入呢?

这个示例,你或许似曾相识:

@Component

public class SonHolder {

@Autowired

private static Son son;

public static Son getSon() {

return son;

}

}

然后“正常使用”这个组件:

@Autowired

private SonHolder sonHolder;

@Transaction

public void method1(){

...

sonHolder.getSon().toString();

}

运行程序,结果抛错:

Exception in thread "main" java.lang.NullPointerException

...

很明显,getSon()得到的是一个null,所以给你扔了个NPE。

295f5a0da17e34b7fe7609705331b254.png

版本约定

本文内容若没做特殊说明,均基于以下版本:

JDK:1.8

Spring Framework:5.2.2.RELEASE

正文

说起@Autowired注解的作用,没有人不熟悉,自动装配嘛。根据此注解的定义,它似乎能使用在很多地方:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,

ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Autowired {

boolean required() default true;

}

本文我们重点关注它使用在FIELD成员属性上的case,标注在static静态属性上是本文讨论的中心。

说明:虽然Spring官方现在并不推荐字段/属性注入的方式,但它的便捷性仍无可取代,因此在做业务开发时它仍旧是主流的使用方式

场景描述

假如有这样一个场景需求:创建一个教室(Room),需要传入一批学生和一个老师,此时我需要对这些用户按照规则(如名字中含有test字样的示为测试帐号)进行数据合法性校验和过滤,然后才能正常走创建逻辑。此case还有以下特点:

用户名字/详细信息,需要远程调用(如FeignClient方式)从UC中心获取

因此很需要做桥接,提供防腐层

该过滤规则功能性很强,工程内很多地方都有用到

有点工具的意思有木有

阅读完“题目”感觉还是蛮简单的,很normal的一个业务需求case嘛,下面我来模拟一下它的实现。

从UC用户中心获取用户数据(使用本地数据模拟远程访问):

/**

* 模拟去远端用户中心,根据ids批量获取用户数据

*

* @author yourbatman

* @date 2020/6/5 7:16

*/

@Component

public class UCClient {

/**

* 模拟远程调用的结果返回(有正常的,也有测试数据)

*/

public List getByIds(List userIds) {

return userIds.stream().map(uId -> {

User user = new User();

user.setId(uId);

user.setName("YourBatman");

if (uId % 2 =

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值