|
|
|
[
Permlink
| « Hide
]
Ben Gunter - 14/Oct/08 05:39 PM
This is my version. I added documentation, support for autodiscovery, and a postProcess(..) method.
Very nice....would this ObjectFactory also be used to create instances of other Stripes objects?
- ActionBeans - ActionBeanContext - Interceptors - ExceptionHandler - Formatters - TypeConverters - TagErrorRenderer Just about everywhere newInstance() is called....? That has been discussed. Personally, I like the idea. I only added calls to it from the couple of spots I know we all agree on. If no one is opposed to using the ObjectFactory everywhere else, I'll make the necessary changes.
We've all been discussing this on IRC, and here is what we have decided, as I understand it. If I mess something up, please correct it.
- ObjectFactory should be an interface that extends ConfigurableComponent and declares a single method: newInstance(Class<?>) - We will provide a DefaultObjectFactory that just calls Class.newInstance() - The Configuration interface will declare a new getObjectFactory() method - All calls to Class.newInstance() will be replaced with a call to ObjectFactory.newInstance(Class) And this is still targeted at 1.5.1? Adding methods to interfaces means a major backward compatibility break ;) (Just kidding, I don't expect many people to implement Configuration themselves. Besides, there has been an ActionResolver change in 1.3.2, IIRC.)
Kidding aside, why are the configurable components that already have a factory listed (in Freddy's comment)? I understand the beauty of having a single place to post-process newly created beans, but it would create yet another layer of abstraction, something I thought Stripes has always been trying to avoid. Another thought: maybe ReflectUtil#getInterfaceImplementation could be refactored into DefaultObjectFactory as well, then.
Levi: Yes! I've had the same thought several times and keep forgetting to write it down. That definitely belongs in the same place since that behaviour should ideally be extensible/overridable
Could you change the visibility of SpringHelper#findSpringBean(...) from protected to public please? (I have a SpringObjectFactory implementation to share, and this would eliminate some otherwise redundant code in its implementation).
This should eliminate spring helper / interceptor entirely. All action beans, interceptors, etc, etc, could be wired in the xml application context and use normal setter injection!
major +1 from me Sorry if we're hijacking the comments for Spring-specific discussion, but to respond to John: I don't think that @SpringBean and its infrastructure should be eliminated. Reasons:
* Not breaking existing code that relies upon it * Having public getters/setters on ActionBeans for Spring dependencies is a bit of a security risk when exposed to Stripes binding. @SpringBean allows Spring dependencies to be injected into private fields. About declaring all that stuff in XML: For a typical project, I think it would get really tedious to have to explicitly declare lots of Stripes components in XML. Not very Stripey! I have a SpringObjectFactory that dynamically registers ActionBeans as Spring Beans with prototype scope. My thinking is that dependencies would be satisfied either by Spring's @Autowired, or by Stripes' @SpringBean if security is a concern. As far as I've heard, lot of the interest in a Spring or Guice ObjectFactory implementation is less for the dependency-injection support and more for the cross-cutting concerns like security and transactions. Doing it dynamically avoids having to coordinate Spring bean-naming and still supports the injection of other XML-defined beans as well as Autowired stuff. Chris: Since Spring 2.5 you don't need to register each bean in the Context XML file, you can use @Component and component scan for that.
Per conversation on IRC, add MultipartWrapper to Freddy's list of Stripes components that ObjectFactory would handle:
- ActionBeans - ActionBeanContext - Interceptors - ExceptionHandler - Formatters - TypeConverters - TagErrorRenderer - MultipartWrapper Wait, is this change meant to give the developer access to instantiation of action bean properties? Or is it for stripes components?
If it's both (I think we need both), do you think they should be separated into ObjectFactory and StripesComponentFactory? I know we would probably have very different logic in both cases, stripes components would have spring beans injected, model objects may have some default values etc. It would be more dev friendly if the stripes level instantiation was in a totally different area than business entity instantiation. StripesComponentFactory would instantiate ObjectFactory ... =) Thoughts? I've added my SpringObjectFactory work to the Stripes Stuff project (http://www.stripes-stuff.org/).
See the the Stripes Users Mailing List for details. For feedback, please contact me directly, or use the ML. I think we're settled on the API at this point. There might still be some minor changes, but it's basically done. Please give it a try and let us know how it goes. Closing as resolved, but feel free to continue commenting.
Ben, can you clarify this for us real quick:
Do we now have access to the instantiation of A) fields in the action bean and/or B) action beans and stripes components themselves? After initialization, everything instantiated by Stripes (type converters, formatters, action beans, action bean contexts, everything during binding) is initalized through the ObjectFactory. You have access to it all.
thank you, that is exactly what i wanted to hear. So much quirky glue code to tie stripes and spring together will be getting deleted.
great job Since we didn't document this in these comments earlier, I'll do so now. The preferred way to post-process new objects in Stripes is to implement an ObjectPostProcessor<T> and drop it into your extensions package. You also still can extend DefaultObjectFactory and override postProcess(Object), but that is a little less flexible. DefaultObjectFactory uses the same strategy used by DefaultFormatterFactory to find a post-processor based on interfaces and inheritance, which enables you to write, for example, an ObjectPostProcessor<ActionBean>, drop it in place and not have to worry about whether the object you're handed is an ActionBean or not.
There are some more advanced cases where you'd need to extend DefaultObjectFactory, though. One Striper did so to add constructor injection, which has to be done instead of the no-arg constructor call by DefaultObjectFactory. We've decided that 1.5.1 will be bug fixes only so I'm removing this from 1.5.1. The commits that have been made for this issue to the 1.5.x branch will be rolled back. Look for this new feature in 1.6.
|
||||||||||||||||||||||||||||||||||||||||||||||