Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @在@Service中自动连线?_Java_Spring - Fatal编程技术网

Java @在@Service中自动连线?

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

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

@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配置是什么样子的?您确定您的组件扫描定义包含包含ns
    Searcher
    class?为所有人干杯,尤其是Luiggi和M.Deinum,使用@PostConstruct works!一切都运行良好,不再出现空值:)感谢使用基于构造函数的依赖项注入的替代方案,我只是尝试了一下,效果也很好。与@PostConstru相比,它似乎更干净了一点ct解决方案。+1用于构造函数依赖项注入!使测试比
    @PostConstruct
    方法容易得多基于构造函数的注入的优点是您无法(轻松地)进行测试创建无效对象。使用
    @PostConstruct
    和默认构造函数,您仍然可以在没有
    ISessionProvider的情况下创建对象。