简体   繁体   中英

Question about instance creation by using Spring framework?

Here goes a command object which needs to be populated from a Spring form

public class Person {

    private String name;
    private Integer age;    

    /**
      * on-demand initialized
      */
    private Address address;

    // getter's and setter's

}

And Address

public class Address {

    private String street;

    // getter's and setter's

}

Now suppose the following MultiActionController

@Component
public class PersonController extends MultiActionController {

    @Autowired
    @Qualifier("personRepository")
    private Repository<Person, Integer> personRepository;

    /**
      * mapped To /person/add
      */
    public ModelAndView add(HttpServletRequest request, HttpServletResponse response, Person person) throws Exception {
        personRepository.add(person);

        return new ModelAndView("redirect:/home.htm");
    }

}

Because Address attribute of Person needs to be initialized on-demand, i need to override newCommandObject to create an instance of Person to initiaze address property. Otherwise, i will get NullPointerException

@Component
public class PersonController extends MultiActionController {

    /**
      * code as shown above
      */

    @Override
    public Object newCommandObject(Class clazz) thorws Exception {
        if(clazz.isAssignableFrom(Person.class)) {
            Person person = new Person();
            person.setAddress(new Address());

            return person;
        }
    }

}

Ok, Expert Spring MVC and Web Flow says

Options for alternate object creation include pulling an instance from a BeanFactory or using method injection to transparently return a new instance.

First option

  • pulling an instance from a BeanFactory

can be written as

@Override
public Object newCommandObject(Class clazz) thorws Exception {
    /**
      * Will retrieve a prototype instance from ApplicationContext whose name matchs its clazz.getSimpleName()
      */
    getApplicationContext().getBean(clazz.getSimpleName());
}

But what does he want to say by using method injection to transparently return a new instance ??? Can you show how i implement what he said ???

ATT : I know this funcionality can be filled by a SimpleFormController instead of MultiActionController. But it is shown just as an example , nothing else

I'm pretty sure he means using the lookup-method system as documented in chapter 3 of the spring reference manual

Only down side is that <lookup-method> requires a no arg method rather than the newCommandObject(Class) method of MultiActionController .

this can be solved with something like:

public abstract class PersonController extends MultiActionController {

    /**
      * code as shown above
      */

    @Override
    public Object newCommandObject(Class clazz) thorws Exception {
        if(clazz.isAssignableFrom(Person.class)) {
            return newPerson();
        }
    }                          

    public abstract Person newPerson();
}

in the context file:

<bean id="personController" class="org.yourapp.PersonController">
  <lookup-method name="newPerson" bean="personPrototype"/>
</bean>

The down side is that using this sort of thing is you are kinda stuck with configuring the controller bean via xml it's not possible (certainly in < 3) to do this with annotations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM