两个原因导致Spring @Autowired注入的组件为空

@Controller

public class Controller {

@GetMapping(“/example”)

public String example() {

MyService my = new MyService();

my.doStuff();

}

}

@Service

public class MyService() {

@Autowired

MyRepository repo;

public void doStuff() {

repo.findByName( “steve” );

}

}

当它尝试访问MyRepository自动连接的存储库时,这将在Service中引发NullPointerException,这不是因为Repository的连接有任何问题,而是因为你使用MyService my = new MyService()手动实例化了MyService。要解决此问题,需要自动注入MyService:

@Controller

public class Controller {

@Autowired

MyService service;

@GetMapping(“/example”)

public String example() {

service.doStuff();

}

}

@Service

public class MyService() {

@Autowired

MyRepository repo;

public void doStuff() {

repo.findByName( “steve” );

}

}

@Repository

public interface MyRepository extends CrudRepository<My, Long> {

List findByName( String name );

}

你忘记在某个类使用组件注解或者它的扩展注解


Spring使用组件扫描来查找需要自动注入并放入到IoC容器中的类。基本上,Spring将扫描项目的类路径(或你指定的路径),找到所有@Component注解的类并将其用于自动装配。因此,如果你忘记注解一个类,则该类将不能自动注入,当你尝试使用它时,将得到一个空的实例,从而导致NullPointerException。

@ Service,@ Repository和@Controller都是@Component特殊情景下的子注解,因此要自动注入的任何类都必须使用其中之一进行注释。否则,自动注入将导致实例为空:

public class MyService {

public void doStuff() {

}

}

这样的是没有问题的:

@Service

public class MyService {

public void doStuff() {

}

}


本文仅是阅读英文文档练手,原文如下:

原文

====================================================================

Two reasons why your Spring @Autowired component is null

The Spring framework makes heavy use of Inversion of Control (IoC) to let you inject classes without having to worry about their scope, lifetime or cleanup.

A common error people hit is when they autowire a class and when they try to call a method on it find that it is null and they get a NullPointerException. So why didn’t Spring auto-wire your class for you? Here’s two possible reasons:

YOU INSTANTIATED THE A CLASS MANUALLY


Hi, 2005 called and asked for their code back. Yeah, OK, IoC is like the cool kid on the block and if you are using Spring then you need to be using it all the time. Here’s a code snippet of a Controller, Service and Repository that will result in a NullPointerException.

@Controller

public class Controller {

@GetMapping(“/example”)

public String example() {

MyService my = new MyService();

my.doStuff();

}

}

@Service

public class MyService() {

@Autowired

MyRepository repo;

public void doStuff() {

repo.findByName( “steve” );

}

}

@Repository

public interface MyRepository extends CrudRepository<My, Long> {

List findByName( String name );

}

This will throw a NullPointerException in the service class when it tries to access the MyRepository auto-wired Repository, not because there is anything wrong with the wiring of the Repository but because you instantiated MyService() manually with MyService my = new MyService(). To fix this auto-wire the Service as well:

@Controller

public class Controller {

@Autowired

MyService service;

@GetMapping(“/example”)

public String example() {

service.doStuff();

}

}

@Service

public class MyService() {

@Autowired

MyRepository repo;

public void doStuff() {

repo.findByName( “steve” );

}

}

@Repository

public interface MyRepository extends CrudRepository<My, Long> {

List findByName( String name );

}

YOU FORGOT TO ANNOTATE A CLASS AS A COMPONENT OR ONE OF ITS DESCENDANTS


Spring uses component scanning to find the classes that it needs to auto-wire and insert into classes for IoC. Basically, Spring is going to scan the project’s classpath (or paths you specified), find all of the @Component classes and make them available for auto-wiring. So if you forget to annotate a class it will not be auto-wired and when you try and use it you will get a null and a NullPointerException.

@Service, @Repository and @Controller are all specializations of @Component, so any class you want to auto-wire needs to be annotated with one of them. So auto-wiring this will cause a null:

结局:总结+分享

看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了Java互联网工程师面试1000题,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱

  • Java互联网工程师面试1000题

image.png

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。

  • 程序员代码面试指南–IT名企算法与数据结构题目最优解

image.png

  • 其余像设计模式,建议可以看看下面这4份PDF(已经整理)

image.png

  • 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。

image.png

以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!

少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。

  • 程序员代码面试指南–IT名企算法与数据结构题目最优解

[外链图片转存中…(img-L2bRIdf4-1721168704478)]

  • 其余像设计模式,建议可以看看下面这4份PDF(已经整理)

[外链图片转存中…(img-bQYBgLz9-1721168704478)]

  • 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。

[外链图片转存中…(img-ruHFrWJk-1721168704478)]

以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值