@Autowired for @ModelAttribute

时间:2012-02-12 21:35:18

标签: spring spring-mvc autowired modelattribute

我是Spring的新手,我遇到了以下问题。

我有以下控制器,其中@Autowired完美运行(尝试调试并且工作正常)。

@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";
    }
}

但是当我提交表单时,我的RegistrationForm中的@Autowired字段仍然为空。

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...
}

这是表单的HTML / JSTL:

<form:form method="POST" modelAttribute="rf">
    ...
</form:form>

任何人都可以帮助我吗?

谢谢。

(灵感来自SpringSource论坛上的this post

2 个答案:

答案 0 :(得分:1)

你在这里混淆了你的概念。对于Spring管理的bean,您使用@Component@Autowired,对于用于绑定表单数据的临时,一次性对象,使用@ModelAttribute。两者不应该混在一起。 Spring上会忽略@Component上的@AutowiredRegistrationForm注释,因为它们不适合这种情况。

RegistrationForm这样的类应该代表表单数据,而不是别的。通常,控制器会询问RegistrationForm用户ID,然后从DAO本身查看实际的User对象。如果您希望RegistrationForm查找User本身,那么当控制器要求RegistrationForm对象时,您的控制器需要手动将DAO提供给User

就春季论坛上的那篇文章而言,你会注意到它从未收到答案。从中获取灵感并不是一个好的来源。

请注意,我并不是说希望将bean自动装入表单后退对象是一个坏主意,我只是说Spring不会这样做。

答案 1 :(得分:1)

如果您在模型上使用@Configurable批注,并在gradle文件上使用此aspectJ配置,它将起作用:

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
    )
}

通过这种方式,aspectJ将生成执行自动布线的代码。

@Configurable
public class RegistrationForm
{
   ...
}