@Autowired在@Service?

Tin*_*Sky 5 java spring

我无法让@Autowired在@Service注释的类中工作,自动变量始终为null.让我解释:

@Service
public class Searcher extends Thread implements ISearcher {
@Autowired
protected ISessionProvider sessionProvider; <-- always null
...
public Searcher() {
sessionProvider.doSomeStuff();
}
Run Code Online (Sandbox Code Playgroud)

sessionProvider总是为null.

奇怪的是@Controller中的相同autowire确实有效:

@Controller
@RequestMapping("/search")
@Secured({ "ROLE_USER" })
public class SearchController  extends BaseController {
@Autowired
protected ISessionProvider sessionProvider; <-- does work 
@Autowired
protected ISearcher searcher;
Run Code Online (Sandbox Code Playgroud)

最后一行抛出异常,因为Searcher的构造函数(实现ISearcher)尝试访问sessionProvider,它是null.

我不确定我可能做错了什么,看起来Spring并没有自动装配Searcher中的ISessionProvider.

可能是春天首先在SearchController中自动装配Searcher,但它应首先在Searcher中自动装配SessionProvider,然后在SearchController中自动装配Searcher.如果没有有效的SessionProvider,则无法自动装配搜索者.困惑我的大脑;-)

有人可以提供帮助大脑吗?

[编辑]

  • 组件扫描包括我的服务,控制器和所有内容,只需检查.
  • 我之前的界面确实不是很好(老习惯)
  • 不确定这是否是一个"重复"的问题,主要是因为我没有做任何与"新"有关的事情,我让春天做所有艰苦的工作,但我会更好地看一眼.

Lui*_*oza 10

Spring将首先创建bean实例,然后注入bean.您正在尝试在创建当前bean时访问注入的bean,因此bean将是null.这是默认行为.

如果您希望/需要在创建bean之后执行任何逻辑,请使用@PostConstruct修饰方法,该方法在创建bean 并注入所有依赖项后调用.这是一个示例:

@Service
public class Searcher extends Thread implements ISearcher {

    @Autowired
    protected ISessionProvider sessionProvider;

    public Searcher() {
        //nothing should be here...
    }

    @PostConstruct
    public void init() {
        sessionProvider.doSomeStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)


M. *_*num 6

在构造bean之后,Spring只能进行依赖注入.您正在构造函数中调用该方法,并且此时ISessionProvider尚未注入,因此它null反过来导致了一个很好的方法NullPointerException.

你有2个解决方案

  1. 将代码从构造函数移动到使用注释的方法 @PostConstruct
  2. 更改默认的no-arg构造函数以获取参数并使用它来执行依赖注入而不是@Autowired field.

解决方案1:将该代码移动到使用注释的方法@PostConstruct.

@Service
public class Searcher extends Thread implements ISearcher {
    @Autowired
    protected ISessionProvider sessionProvider;
    ...
    public Searcher() {}

    @PostConstruct
    public void init() {
        sessionProvider.doSomeStuff();
    }
Run Code Online (Sandbox Code Playgroud)

解决方案2:使用基于构造函数的依赖注入.

@Service
public class Searcher extends Thread implements ISearcher { 

    protected final ISessionProvider sessionProvider;

    @Autowired
    public Searcher(ISessionProvider sessionProvider) {
        this.sessionProvider=sessionProvider;
        sessionProvider.doSomeStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)