MVC Datasource: controller or model? - model-view-controller

Just a quick question: In an OOP MVC application, one key principle is the seperation of responsibilities. I therefor think that a model and the object that fetches the model from a database, file, xml, webservice, etc. should be seperated from the model itself. This can for example be done by implementing a datamapper.
However, what do I do when I have a model that can be loaded from different sources? Should the model be in charge of the datasource, or is this the responsibility of the controller?
An simple example could be a config class that can be loaded from a database or a file. Should the controller instruct the datasource, or should the model know when to load the config info from a database or a file?

have used frameworks were the datasource is informed by the controller MachII, Model-Glue (Coldfusion frameworks) and also from the model layer (ColdSpring) - like Spring in Java.
I think the key thing is to use what makes more sense to you, keep the coupling to a minimum and be consistent, meaning don't put datasource or object dependencies in multiple places.
You could also consider using a service type object to abstract the datasource and have it serve either who it likes.
That IOC file could look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="chartShareObj" class="model.charts.ChartShared" autowire="byType" />
<bean id="trendChartObj" class="model.charts.TrendChart" autowire="byType" />
<bean id="adminRightsDA0" class="org.datamentor.institution.RightsDAO">
<constructor-arg name="dsn">
<value>${dsn_dm}</value>
</constructor-arg>
</bean>
<bean id="assessmentManager" class="model.assessment.Manager">
<constructor-arg name="dsn">
<value>${dsn_au}</value>
</constructor-arg>
</bean>
</beans>
You can see the different datasources specified by args via args defined in a controller.

Based on your situation and response I would suggest looking into dependency injection. You can then let it handle determining which data source to use based on whatever set of variables you want to let it determine things by. This is what I use when I have multiple data sources and want to have the data source determined by some predetermined factors I have chosen.
http://en.wikipedia.org/wiki/Dependency_injection
As to who should handle the injection, I leave that to a repository factory and simply ask for an interface in the controller. The factory then determines based on the dependency injection which repository to provide.
Example:
Dependency Injection in an global Infrastructure class:
Bind<INewsArticleRepository>().ToMethod(context => NewsRepositoryFactory.Create((NewsRepositoryFactory.RepositoryType)Enum.Parse(typeof(NewsRepositoryFactory.RepositoryType), ConfigurationManager.AppSettings["NewsArticleRepositoryProvider"])));
Repository Factory
public static INewsArticleRepository Create(RepositoryType type)
{
switch (type)
{
case RepositoryType.Mock:
return new MockNewsArticlesRepository();
case RepositoryType.Sql:
return new SqlNewsArticleRepository();
default:
throw new NotImplementedException();
}
}
Call in the controller for a repository
private INewsArticleRepository newsItemRepository;
public NewsController(INewsArticleRepository newsItemRepository)
{
this.newsItemRepository = newsItemRepository;
}

They way I do it in Coldbox is using CB's INJECT method in the model. In the cfargument of the constructor, I specify:
<cfargument name="dsn" type="any" inject="coldbox:datasource:dsn">
And that's from specifying the dsn in the coldbox.cfc file, and calling it "dsn". I keep it generic so I can copy this stuff to other projects and only have to change the DSN name in the coldbox.cfc.
But then after doing that, you get the dsn like this:
variables.dsn = arguments.dsn.getName();
I hope this helps, at least a little.
Rob

Related

Spring config and runtime separation

When using Spring it is rather cumbersome to incorporate runtime data in bean construction. While there are techniques to circumvent this separation, I have a feeling that it was put in place for a reason. My question is whether this is a known paradigm, and if there is any litterature discussing it. Personally I find that it has both advantages and drawbacks, depending on the dynamicity of the app.
You have at least five well known methods to pass runtime data to beans configuration:
Use ApplicationContextInitializer to add PropertySources to the Enviroment.
Use SPEL to inject dependencies.
Use FactoryBeans.
Use the factory-bean and factory-method attributes.
If you write the class that need the runtime data, you only need to inject the
collaborator that provide it.
For example
<bean id="requestAttributeReader" class="example.RequestAttributeReader" />
<bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
<property name="a" value="#{requestAttributeReader.a}" />
</bean>
Class RequestAttributeReader {
public String getA() {
return RequestContextHolder.getAttributes().getAttribute("a");
}
}
EDIT
The bean description files of an IoC container lets you to configure implementors on application beans. This is normally a static definition of the implementation classes that you want to use for a concrete configuration, so xml it's good for it.
If you need to choose an implementor based on runtime then you need to write code to choose them and then inform the container.
for example, using PropertySources and PropertyPlaceholderConfigurer:
String service = "example.NormalService";
if (BOSS_USERNAME.equals(System.getProperty("user.name")))
service = "example.BossService";
ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service));
<bean id="service" class="${service}" />
The same could be done with a ServiceFactoryBean, a external ServiceFactory, SPEL and so on...
Maybe, you are interested on replacing implementations at runtime, ie changing the Service implementation in all beans that depends on when the container is already refreshed. (without destroy and refresh).
As far as I know, the framework don't provides a clear way to do it.
Sounds like you should look at spring binding, eg:
public String create(#Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
So this will take request params that match the fields in the Market object and set them in that object. It will also validated the params/object since there is the #Valid annotation.
This binding can be customised with PropertyEditors or Converters.
If the market object is annotated #Configurable, it can use #Autowired and #Value annotations to configure the bean when spring creates it.

Spring Dependency injection scope confusion

I am new to Spring DI and i am implimenting DI for the first time in my webapplication.
it seems i am doing somehing wrong and it related the way i am using spring scope.here is my problem
i have a serive class where i am injecting various other object in order to achieve the desired functionality
here is my spring file entries
<bean id="ImportServiceImpl" class="ImportServiceImpl" factory-method="getInstance">
<property name="browseDirectory" ref="browseDirectoryImpl"/>
<property name="xmlUnmarshaller" ref="xmlUnmarshallerImpl"/>
<property name="Adaptar" ref="AdaptarImpl"/>
<property name="DAOService" ref="DAO"/>
</bean>
<bean id="browseDirectoryImpl" class="BrowseDirectoryImpl" factory-method="getInstance" />
<bean id="xmlUnmarshallerImpl" class="XMLUnmarshallerImpl"/>
<bean id="AdaptarImpl" class="AdaptarImpl" factory-method="getInstance"/>
now in my adaptarImpl class i have a refrence to some other object which is being initialized in the constructor
private AdaptarImpl(){
foo=new Foo();
}
now for the first time when the server start and this service run fist time everything is fine foo is being initilized to its proper initialization value but for all other subsequent calls Spring is returing refrence to the previous initialized foo object where i want that for each new request a new instance of foo should be created.
it apperas to me that the factory method being used in the above code factory-method="getInstance"
is being called only once when server called and all other subsequent calles returning same refrence where i want a new instance for every request.
here is my facory method
public static ImportServiceImpl getInstance(){
return new ImportServiceImpl();
}
i know i am doing basics wrong in DI but not sure where it is.I am using Struts2 for MVC and for service layer using Spring DI
any help in this regard will be helpful
Thanks
Umesh
I'm not sure I understand your question, but it sounds like you ought to ask Spring to inject the reference to Foo into your AdapterImpl and make its scope "request". If you need Spring to control object creation, don't call "new".
I think you need to look at
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes
and look at table 3.3.

How to create two instances of the same spring controller, each with a different base #requestMapping

I have a spring controller (MyController) which servers data as json.
With a few configuration changes, I will be able to reuse the same controller and have it serve the same data, but as xml, not json.
I'd love to be able to create myControllerInstanceA, and configure it to use /json as a base url, then create myControllerInstanceB and have it use /xml as a base url.
The only way I can think of to do this is to subclass MyController, and set the subclass's #requestMapping to /xml. I'd rather be able to do some configuration in my springap-servlet.xml to achieve the same effect.
Is this possible?
I'm guessing some of you spring wizards reading this might be thinking "why the heck would he want to do that". So I'll explain the techniques i'm using: I'm creating a controller, which adds simple java beans to a ModelAndView. The controller also ads a view. The view takes the java beans and serializes them to json, or to xml, depending on how the controller was configured. I think there is probably a more Spring-ish way to do this, but this approach seemed simple and straightforward enough. Also, it allows me to work with a JSON library I'm familiar with, rather than the one that Spring seems set up to use. Points for anyone who tells me the Spring way to do it -- how to easily serve the same data as either json or xml, reusing controller code as much as possible.
Use ContentNegotiatingViewResolver to resolve the views. This resolve will use different configured views to render the model based on the request's Accepts Header or extension. By default it uses the MappingJacksonJsonView for JSON and you will have to configure an Xml Marshaller for use with the MarshallingView.
With this configuration you can have each annotated method support infinite data formats.
Check out this example.
I'm not sure if you're asking for this, but Spring 3 has ContentNegotiationResolver which can help to return json or xml:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
</bean>
And in the controller you can map json and xml to the same controller method.
#Controller
class MyClass(){
#RequestMapping(value={"/yourURL.json", "/yourURL.xml"})
public Object yourController(){
return Object
}
}

Apply dynamic properties to a bean at runtime

Assume I have a bean DialogBox, with properties for height and width:
public class DialogBox {
int x;
int y;
...
}
In my applicationContext.xml I would define properties as reasonable defaults:
<bean id="dialogbox" class="DialogBox">
<property name="x" value="100"/>
<property name="y" value="100"/>
</bean>
We have multiple clients that use the dialogBox bean, and each wants a custom value for x and y. One route we have discusses is having multiple properties files, one for each client, and have the client id map to the proper file, for example client 123 would map to dialogbox_123.properties:
dialogbox_123.properties:
x=200
y=400
Then at runtime when the bean is requested, spring would look to see if a custom properties file exists for the client, and use those properties, otherwise use the defaults. I am aware of the PropertyOverrideConfigurer, but AFAIK this only works when the context is started so will not work for our purposes. Is there an existing facility in spring to achieve this, or can someone recommend another way?
Use FactoryBean (as already suggested) to customize instantiation.
set scope="prototype" on the bean, so that each time an instance is required, a new one should be created.
In case you want to inject the prototype bean into a singleton bean, use lookup-method (Search for lookup-method here)
I'm not sure if this would fit your case though. Another suggestion would be:
In #PostConstruct methods of your various "clients" set the properties as desired on the already injected dialog window. Like:
public class MyDialogClient {
#Autowired
private Dialog dialog;
#PostConstruct
public void init() {
dialog.setWidth(150); //or read from properties file
dialog.setHeight(200);
}
...
}
Again, in this case, you can play with the scope atrribute.
Take a look at the Spring OSGi Compendium services, they've got a property manager called "managed-properties", which allows you not only to update the properties at runtime, but while the application is running if you select the "container-managed" update strategy.
If I understood the question, you can use a FactoryBean to customize bean creation logic in Spring.

Spring dependency injection or aspect programming

I have a need for methods in several classes that must always follow a specific pre and post pattern.
public void method(X x, Y y ) {
// ************Repeating Part begin ******************/
AFrameworkClass aFrameworkClass = new AFrameworkClass (this.memberVariable,"SomeString");
try {
aFrameworkClass.aFrameworkMethod( x,y);
aFrameworkClass.anotherFrameworkMethod(x,y);
aFrameworkClass.yetAnotherFrameworkMethod(x);
aFrameworkClass.doPreProcessing();
Throwable t = null ;
// ************Repeating Part End ******************/
try {
// code will vary according to the business logic
}
catch (Throwable t) {
// code will vary according to the business logic
}
// ************Repeating Part begin ******************/
aFrameworkClass.doPostProcessing();
}
finally {
aFrameworkClass.doCleanup();
}
// ************Repeating Part End ******************/
}
Is it possible to use Spring framework to accomplish the logic in the repeating parts in this method without having to code those lines over and over again in my various classes? If so how?
Absolutely it can be done with Spring's AOP support. You can apply the first part as "before" advice and the 2nd as "after-finally" advice or you can apply both as "around" advice and programmatically invoke the target method like so:
methodInvocation.invoke(); // returns Object
If you want to declare your aspects in XML you can read about how to do it here:
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema-advice-before
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema-advice-after-finally
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-ataspectj-around-advice
Or if you want to do it with annotations there is info here:
http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-ataspectj
Personally I prefer doing it with XML since the behavior of the aspects can be altered without recompiling the application. Let's say you have a multi-module project where B depends A. A contains reusable advice and is using annotations for order, pointcuts, etc. If you need to change that behavior, you must rebuild A. If you are using XML in project B to configure the aspect from project A, no rebuild of A is needed.
My feeling is that advice is more reusable when you define the behavior in a class and how that behavior is applied in XML.
As an alternative to a full-fledged IoC container, you can achieve the same thing using a delegate. Design a base class with the pre- and post- functions and a delegate to inject your varying business logic function. A "RunProcess" base class function would call the pre- operations, the delegate, then the post- operations.
brd6644 is right, but one thing I've discovered is a problem with Spring AOP is that the advice/advisors cannot be applied to the properties as you are creating the object.
That is, say you have something like
<bean class="...ProxyBeanFactory">
<property name="target">
<bean class="myBean">
<property name="username" value="helloKitty"/>
<property name="password" value="lkajdahdkahjdkhja"/>
</bean>
</property>
</bean>
It is not possible to write an advisor to decrypt the password for myBean, since the property value is being supplied before the proxy is created. You can't apply the password property to the ProxyBeanFactory class, of course. What you really want to do is have setPassword() called on the object returned from the ProxyBeanFactory with the "lkaj..." argument, but that's not possible, it would seem.

Resources