Java @在@Service中自动连线?
我无法让@Autowired在@Service注释的类中工作,Autowired变量始终为null。让我解释一下:Java @在@Service中自动连线?,java,spring,Java,Spring,我无法让@Autowired在@Service注释的类中工作,Autowired变量始终为null。让我解释一下: @Service public class Searcher extends Thread implements ISearcher { @Autowired protected ISessionProvider sessionProvider; <-- always null ... public Searcher() { sessionProvider.doSomeStu
@Service
public class Searcher extends Thread implements ISearcher {
@Autowired
protected ISessionProvider sessionProvider; <-- always null
...
public Searcher() {
sessionProvider.doSomeStuff();
}
@服务
公共类搜索器扩展线程实现ISearcher{
@自动连线
受保护的ISessionProvider sessionProvider;Spring只能在构建bean之后进行依赖注入。您正在构造函数中调用该方法,此时,ISessionProvider
尚未被注入,因此它是null
,这反过来会导致一个不错的NullPointerException
您有两种解决方案
将代码从构造函数移动到用@PostConstruct
更改默认的无参数构造函数以获取参数,并使用该参数执行依赖项注入,而不是@Autowired字段
解决方案1:将该代码移动到带有@PostConstruct
注释的方法
@Service
public class Searcher extends Thread implements ISearcher {
@Autowired
protected ISessionProvider sessionProvider;
...
public Searcher() {}
@PostConstruct
public void init() {
sessionProvider.doSomeStuff();
}
@Service
public class Searcher extends Thread implements ISearcher {
protected final ISessionProvider sessionProvider;
@Autowired
public Searcher(ISessionProvider sessionProvider) {
this.sessionProvider=sessionProvider;
sessionProvider.doSomeStuff();
}
}
解决方案2:使用基于构造函数的依赖项注入。
@Service
public class Searcher extends Thread implements ISearcher {
@Autowired
protected ISessionProvider sessionProvider;
...
public Searcher() {}
@PostConstruct
public void init() {
sessionProvider.doSomeStuff();
}
@Service
public class Searcher extends Thread implements ISearcher {
protected final ISessionProvider sessionProvider;
@Autowired
public Searcher(ISessionProvider sessionProvider) {
this.sessionProvider=sessionProvider;
sessionProvider.doSomeStuff();
}
}
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();
}
}
我没有做测试,但我认为问题在于,在类搜索器
中,您创建了一个无参数构造函数,并且在那里使用了“自动连线”bean。我猜您将得到NPE。因为spring将使用默认构造函数(通过反射)实例化您的搜索器
如果您没有指定一个,也就是说,它将使用您创建的无参数构造函数,但此时“autowired”bean还没有被注入
如果您想在bean实例化后立即执行某些操作,可以将逻辑代码包装在一个方法中,并使用@PostConstruct
对其进行注释。我也遇到了同样的问题,但我不能使用@PostConstruct
,因为我没有使用doinit
。我有一个简单的方法,即获取rom语言服务。
我的lang服务在这里是null
,但在另一个控制器中它不是null
,它正在自动连接
@Service
@Configurable(preConstruction = true, autowire = Autowire.BY_NAME)
public class FormSelectLanguageHandler extends SimpleTagSupport {
@Autowired
private LangService langService;
public List<Lang> getLanguages(){
Sessions session = (Sessions) getJspContext().findAttribute("SHLSESSION");
List<Lang> languages=new ArrayList<Lang>();
//List<Lang> allLanguages = langService.findAllLangs();
List<Lang> all =new ArrayList<Lang>();
if (isRenderLangLabel()) {
all = langService.findByDisplayOrderAsc();
} else {
all = langService.findByNameOrderByNameAsc();
}
Long companyId = (null == session || null == session.getCompany())? null:session.getCompany().getId();
}
}
@服务
@可配置(预构造=true,自动连线=autowire.BY_NAME)
公共类FormSelectLanguageHandler扩展了SimpleTagSupport{
@自动连线
私人语言服务;
公共列表getLanguages(){
Sessions session=(Sessions)getJspContext().findAttribute(“SHLSESSION”);
列表语言=新的ArrayList();
//列出所有语言=langService.findAllLangs();
List all=new ArrayList();
if(isRenderLangLabel()){
all=langService.findbydisplayerderasc();
}否则{
all=langService.findByNameOrderByNameAsc();
}
Long companyId=(null==会话| | null==会话.getCompany())?null:会话.getCompany().getId();
}
}
如果您承诺从接口名称的开头删除I
,则我可能会提供帮助…您混合使用服务组件和线程的事实表明您的设计需要一些返工。您的spring配置是什么样子的?您确定您的组件扫描定义包含包含nsSearcher
class?为所有人干杯,尤其是Luiggi和M.Deinum,使用@PostConstruct works!一切都运行良好,不再出现空值:)感谢使用基于构造函数的依赖项注入的替代方案,我只是尝试了一下,效果也很好。与@PostConstru相比,它似乎更干净了一点ct解决方案。+1用于构造函数依赖项注入!使测试比@PostConstruct
方法容易得多基于构造函数的注入的优点是您无法(轻松地)进行测试创建无效对象。使用@PostConstruct
和默认构造函数,您仍然可以在没有ISessionProvider的情况下创建对象。