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, HttpServletR开发者_高级运维esponse 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.
精彩评论