我一整天都在看我的代码,我找不到原因。存储库(@Repository)运行正常,它是 @Service 字段,我一直无法让它自动装配,我一直在努力,因为一切都很好
调度的servlet:
<mvc:annotation-driven />
<context:component-scan base-package="com" />
com.repository
Repo.java
package com.repository;
import com.domain.Student;
import java.util.List;
public interface Repo { public List<Student> getAllSiswa(); }
RepoImplement.java
import com.domain.Student;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
@Repository
public class RepoImplement implements Repo {
List<Student> ls = new ArrayList<>();
public RepoImplement(){
Student s1 = new Student();
s1.setNama("paul");
Student s2 = new Student();
s2.setNama("robert");
ls.add(s1);
ls.add(s2);
}
@Override
public List<Student> getAllSiswa() {
return this.ls;
}
}
package com.service;
Serve.java
import com.domain.Student;
import java.util.List;
public interface Serve {
void changeName(String namaBaru);
public List<Student> newList();
}
我怀疑这里有什么问题
ServeImplement.java
import com.domain.Student;
import com.repository.Repo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ServeImplement implements Serve {
@Autowired
public Repo repo;
List<Student> s = repo.getAllSiswa(); // THIS IS SUSPECTING ME.
@Override
public void changeName(String namaBaru) {
s.get(0).setNama(namaBaru); // get first Student, then update its name.
}
@Override
public List<Student> newList() {
return this.s;
}
}
controller2.java (这是服务学生的映射请求)
package com.controlller;
import com.domain.Student;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.service.Serve;
@Controller
public class controller2 {
@Autowired
public Serve serv;
@RequestMapping("/changename")
public ModelAndView sdaf() {
serv.changeName("New name");
List<Student> list = serv.newList();
return new ModelAndView("page2", "out", list);
}
}
错误:
创建名为'controller2'的bean时出错:注入自动装配 依赖失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:不能 autowire字段:public com.service.Serve com.controlller.controller2.serv;嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建文件中定义名为'serveImplement'的bean [C:\用户\汉斯\文件\的NetBeansProjects \ WebApplication2 \构建\网络\ WEB-INF \类\ COM \服务\ ServeImplement.class]: bean的实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:不能 实例化bean类[com.service.ServeImplement]:构造函数抛出 例外;嵌套异常是java.lang.NullPointerException
答案 0 :(得分:4)
您需要了解自动装配,或者事实上Java的工作原理。
Spring必须创建ServImpl类的实例,并使用存储库bean填充字段repo
。它使用反射来做到这一点,但它的作用基本上等同于以下代码:
ServImpl s = new ServImpl();
s.repo = theRepoBean;
因此,在构造函数执行完后,您会看到s.repo
变为非null 。并且,在执行构造函数时,执行以下代码行:
List<Student> s = repo.getAllSiswa();
此时,repo
尚未初始化。所以它是空的。所以你得到一个NullPointerException。
使用构造函数注入而不是字段注入,或使用@PostConstruct
带注释的方法。
请将您的字段设为私有而非公开。
也就是说,存储库的目标通常是从数据库中获取数据。学生可以在数据库中修改,删除或创建。因此,初始化您的服务字段并始终返回相同的列表会破坏拥有回购的重点。您应该在每次调用时从newList()调用repo.getAllSiswa()
,以获取最新的最新学生列表。
答案 1 :(得分:1)
由于Autowired
字段在构建后立即发生,因此您需要更改代码才能使其生效。
这应该有效:
@Service
public class ServeImplement implements Serve {
public Repo repo;
List<Student> s;
@Autowired
public ServeImplement(Repo repo) {
this.repo = repo;
s = repo.getAllSiswa();
}
@Override
public void changeName(String namaBaru) {
s.get(0).setNama(namaBaru); // get first Student, then update its name.
}
@Override
public List<Student> newList() {
return this.s;
}
}
此外,在构造函数上使用Autorwired
注释,如果实例不必更改,则允许您将字段标记为final
。