问题
I'm very new to Spring and I'm encountering the following problem.
I've got the following Controller, in which the @Autowired works perfectly (tried debugging and it works fine).
@Controller
@RequestMapping(value = "/registration")
@SessionAttributes("rf")
public class RegistrationController
{
@Autowired
UserJpaDao userDao;
@RequestMapping(method = RequestMethod.GET)
@Transactional
public String setupForm(Model model) throws Exception
{
model.addAttribute("rf", new RegistrationForm());
return "registration";
}
@RequestMapping(method = RequestMethod.POST)
@Transactional
public String submitForm(@ModelAttribute("rf") RegistrationForm rf, Model model) throws Exception
{
// ...
User user = rf.getUser();
userDao.save(user);
// ...
return "registration";
}
}
But when I submit my form, the @Autowired field in my RegistrationForm remains null.
RegistrationForm.java:
@Component
public class RegistrationForm
{
@Autowired
CountryJpaDao countryDao;
// ... fields...
public RegistrationForm()
{
}
@Transactional
public User getUser() throws InvalidUserDataException
{
//...
Country c = countryDao.findByCode("GB"); // Throws java.lang.NullPointerException
// ...
}
// ... getters/setters...
}
Here is the form's HTML/JSTL:
<form:form method="POST" modelAttribute="rf">
...
</form:form>
Can anyone help me?
Thank you.
(inspired by this post on SpringSource forums)
回答1:
You're mixing up your concepts here. You use the likes of @Component
and @Autowired
for Spring-managed beans, and @ModelAttribute
for transient, throwaway objects that are used to bind form data. The two should not be mixed. Your @Component
and @Autowired
annotations on RegistrationForm
will be ignored by Spring, because they're not appropriate in that context.
Classes like RegistrationForm
should represent the form data, and nothing else. Typically, the controller would ask RegistrationForm
for the user ID, and would then look at the actual User
object from the DAO itself. If you want RegistrationForm
to look up the User
itself, then your controller needs to manually supply the DAO to RegistrationForm
when it asks for the User
object.
As far as that post on the Spring forum is concerned, you'll notice that it never received an answer. It's not a good source to take inspiration from.
Note that I'm not saying that desiring to autowire beans into a form back object is a bad idea, I'm just saying that Spring doesn't do that.
回答2:
It would work if you use the @Configurable annotation on your model, and this aspectJ configuration on your gradle file:
compileJava << {
ant.taskdef(
resource: 'org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties',
classpath: configurations.compile.asPath)
ant.iajc(
inpath: sourceSets.main.output.classesDir.absolutePath,
classpath: configurations.compile.asPath,
aspectPath: configurations.aspects.asPath,
destDir: sourceSets.main.output.classesDir.absolutePath
)
}
In this way aspectJ will generate code that does the auto wiring.
@Configurable
public class RegistrationForm
{
...
}
来源:https://stackoverflow.com/questions/9252905/autowired-for-modelattribute