Spring RegisterSingleton - spring

I have a following object:
public class TestObject
{
public String Something { get; set; }
}
and a following objects file:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd">
<object id="TestObject" type="SpringTest.TestObject" autowire="byName"/>
</objects>
What I would like to do is to register singleton and get the TestObject. I am doing this like so:
IConfigurableApplicationContext context = new XmlApplicationContext("objects.xml");
context.ObjectFactory.RegisterSingleton("Something", "something to test");
object obj = context.GetObject("TestObject");
But the objects property Something is always null. I think that this should work or am I doing something wrong?
Many thanks!

I'm not sure what the problem statement is exactly (never used Spring for .NET). But if you want what Don Kirkby suggest you should lookup TargetSources in the reference documentation (assuming that the .NET implementation has them, too).

I think your Something property is not getting set because singletons are instantiated when the application context is instantiated. When you call RegisterSingleton, the TestObject has already been created. The bean wiring is only done when a bean is created.
You might be able to work around this problem by making the singleton instantiate lazily. That way it isn't instantiated until the first time it's requested. Hopefully, that's after you've registered the other singletons it needs.
I don't know exactly what you're trying to accomplish, but if I wanted to change the wiring between some singleton beans at run time without making the beans aware of it, I would introduce some wrapper objects. Each wrapper would implement an interface and then just delegate all methods to its current target bean. To change the wiring, you just change the wrapper's target.
Update: as yawn suggested, Spring.NET has hot-swappable target sources that let you swap out the implementation of a bean at run time. Here's some sample code from the documentation that shows how to swap the bean implementation:
HotSwappableTargetSource swapper =
(HotSwappableTargetSource) objectFactory.GetObject("swapper");
object oldTarget = swapper.swap(newTarget);
The XML definitions in the documentation look like this:
<object id="initialTarget" type="MyCompany.OldTarget, MyCompany">
</object>
<object id="swapper"
type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop">
<constructor-arg><ref local="initialTarget"/></constructor-arg>
</object>
<object id="swappable"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="targetSource">
<ref local="swapper"/>
</property>
</object>

Why aren't you using scope="singleton" if you want a singleton or am I missing something?

Related

MVC Datasource: controller or model?

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

Why is there a need to specify the class in both the xml file and in the getBean() method in Spring

This might be an obvious but I'm having a hard time understanding why we need to define the class of a bean in two places....
From the spring reference manual...
...
<bean id="petStore"
class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
// retrieve configured instance
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
Shouldn't the xml fine be enough for the container to know the class of petStore?
You can use the following method:
context.getBean("petStore")
However, as this returns a java.lang.Object, you'd still need to have a cast:
PetStoreServiceImpl petstore = (PetStoreServiceImpl)context.getBean("petStore");
However, this could lead to problems if your "petStore" bean is not actually a PetStoreServiceImpl, and to avoid casts (which since the advent of Generics are being seen as a bit dirty), you can use the above method to infer the type (and let's spring check whether the bean you're expecting is really of the right class, so hence you've got:
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
Hope that helps.
EDIT:
Personally, I would avoid calling context.getBean() to lookup methods as it goes against the idea of dependency injection. Really, the component that uses the petstore bean should have a property, which can then be injected with the correct component.
private PetStoreService petStoreService;
// setter omitted for brevity
public void someotherMethod() {
// no need for calling getBean()
petStoreService.somePetstoreMethod();
}
Then you can hook up the beans in the application context:
You could also do away with the configuration via XML and use annotation to wire up your beans:
#Autowired
private PetStoreService petStoreService;
As long as you've got
in your spring context, the "petStore" bean defined in your application context will automatically be injected. If you've got more than one bean with the type "PetStoreService", then you'd need to add a qualifier:
#Autowired
#Qualifier("petStore")
private PetStoreService petStoreService;
There's no requirement to specify the class in the getBean() method. It's just a question of safety. Note there's also a getBean() that takes only a class so that you can just look up beans by type instead of needing to know the name.

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.

when spring bean is loaded and if i have a constructor and setters which one will be called first?

This is a basic question - when spring bean is loaded and if i have a constructor and setters which one will be called first?
Thanks
The constructor must be called before any setter methods are called. Use the init-method to tell Spring to invoke some logic after the setters are called:
<bean class="my.CoolClass" init-method="startup">
<constructor-arg value="Foo" />
<property name="bar" value="baz" />
</bean>
Doesn't the constructor have to be called first? The setters are instance methods so that can't called until the object is instantiated.
I don't think Spring provides any guarantees about the order in which setters are called. It would be good practice to make your beans work regardless of which order the setters are called. If you want to do some processing after all the setters have been called, you might find that it's convenient to use a post construction method. Or if you are using XML configuration rather than annotations, an initialization method might suit.
I wrote simple XML config and step through Spring source code in debugger.
Seems that with Spring 3.x it's possible to combine constructor-arg and property in XML bean definition (check doCreateBean in AbstractAutowireCapableBeanFactory.java, which call createBeanInstance - constructor and populateBean next - setters).
See also https://softwareengineering.stackexchange.com/questions/149378/both-constructor-and-setter-injection-together-in-spring/

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.

Resources