I've been looking into using EasyMock 3's IMockBuilder as a means of generating partial mocks (I know partial mocking may suggest a design flaw, but I'm writing tests for old code). Presumably I can use the deprecated static EasyMock.createMock() methods to create beans in my Spring config, like this:
<bean id="myBean" class="org.easymock.EasyMock" factory-method="createMock">
<constructor-arg value="org.mypackage.MyClass.class" />
</bean>
When creating a partial mock using an IMockBuilder, I need to make several calls to addMockedMethod() in order to define the methods I want mocked. Is there a way I can do this in a Spring XML configuration file? Ideally I'd like all the dependencies of all my beans set by Spring, and don't want to have to override them in my test cases in order to pass in mock objects created in this way.
Thanks
No, XML config isn't capable of that sort of flexibility.
You have two options:
Write an implementation of FactoryBean which creates the mock, configures it, and returns the mock to Spring. See Customizing instantiation logic with the FactoryBean Interface.
Use #Configuration-style configuration in Java, instead of XML style configuration. This is the most flexible approach, and is generally better than XML config. See Java-based container configuration
Related
I am developing Spring MVC app, i need to implement singleton pattern for some kind of utilities, ex: imageuploader and others.
My question is: in what way to implement singleton for this utilities, to initialize beans for these classes and inject where i need like Controllers, Services, DAO?, or to use static field implementation of singleton to keep instance of this class?
First, try to avoid singleton as it's considered to be a bad practice. Also their interactions with other instances are difficult to test and validate, compared to non-singleton instances.
If you absolutely need it, I'd suggest you use a Spring bean so you can exploit the autowiring mechanism and Spring's bean lifecycle.
See the Beans section of the Spring reference doc for more info.
Using a Spring bean as will allow you to easily inject a mock in unit tests. However, you will only be able to access it from other Spring beans (or objects created by Spring beans that pass in a reference to it).
Also see this discussion in this question: Difference between static class and singleton pattern?
Traditionally, you'd use PropertyPlaceholderConfigurer to inject config from properties files into a Spring web-app. This blog discusses a variety of newer ways to do this with Spring.
I am using the dynamic language support in spring for Groovy to setup a groovy class that implements one of my interfaces in a .groovy file. In the spring docs the recommended approach to configure a dynamic language bean is in the XML as follows:
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
<lang:property name="message" value="I Can Do The Frug" />
</lang:groovy>
I can get this to work, but I was wondering is there a way to configure a dynamic language bean through annotation instead of through XML. The scenario I am thinking of is if I created a new class implementation for an interface that is currently not configured in the XML. I would have to stop the container in order to add the entry to the spring XML. This defeats the purpose of dynamic language support in that I want to be able to hot deploy the new service implementation.
So, my question is, is there an equivalent annotation approach to configure lang:groovy as shown above in XML that I can include in my .groovy file or elsewhere that will force spring to scan and compile the .groovy file?
Our application contains struts and spring. Struts action classes are also configured as spring beans in applicationContext.xml. Spring class references are wired to action classes using 'property'.
For Ex.,
applicationContext.xml
<bean id="sampleAction" class="com.arizona.sample.action.SampleAction">
<property name="sampleManager" ref="sampleManager" />
</bean>
In SampleAction, I got to write a static method where it uses 'sampleManager' reference. So, I have configured 'sampleManager' as static variable. At runtime I got a NullPointerExcpetion at the place where 'sampleManager' is used. I have concluded that 'sampleManager' ain't get initialized.
Can anyone please help me in this regard?
P.S.: I have provided setSampleManager(..) and also tried with #Autowired.
If you find yourself trying to interact with an inherently non-static object (sampleManager) from a static context (method), then your design has some fundamental flaw in it. Go back and refactor your solution to employ proper OO design, don't try to fix it with some ugly hack.
Wicket has this device called a lazy proxy factory. Given:
<property name="foo" ref="beanx"/>
the idea is to auto-generate a proxy in place of 'beanx', and then only initialize beanx if and when something actually calls a method on it.
It seems as if this might be a core Spring capability. Is it there somewhere?
See LazyInitTargetSource; that might do what you want. It requires use of lazy-init="true" on the target bean as well, though.
Spring singleton beans, the closest thing to what you want, are created when the spring context is initialized: http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes. So I believe the short answer is "no." You can implement your own scope to do this by extending the Spring classes quite easily, though.
Spring session/request scope is implemented using the technique you describe, but it is only intended to handle transitions between scope cardinalities, not instance creation. So spring uses the same concepts, but you'd probably have to create your own implementation.
I have a use case where I need to call a (non-static) method in the bean only-once at the ApplicationContext load up. Is it ok, if I use MethodInvokingFactoryBean for this? Or we have a some better solution?
As a side note, I use ConfigContextLoaderListener to load the Application Context in web application. And want, that if bean 'A' is instantiated just call methodA() once.
How can this be done nicely?
To expand on the #PostConstruct suggestion in other answers, this really is the best solution, in my opinion.
It keeps your code decoupled from the Spring API (#PostConstruct is in javax.*)
It explicitly annotates your init method as something that needs to be called to initialize the bean
You don't need to remember to add the init-method attribute to your spring bean definition, spring will automatically call the method (assuming you register the annotation-config option somewhere else in the context, anyway).
You can use something like:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
This will call the "init" method when the bean is instantiated.
There are three different approaches to consider, as described in the reference
Use init-method attribute
Pros:
Does not require bean to implement an interface.
Cons:
No immediate indication in source code that this method is required after construction to ensure the bean is correctly configured.
Implement InitializingBean
Pros:
No need to specify init-method, or turn on component scanning / annotation processing.
Appropriate for beans supplied with a library, where we don't want the application using this library to concern itself with bean lifecycle.
Cons:
More invasive than the init-method approach.
Use JSR-250 #PostConstruct lifecyle annotation
Pros:
Useful when using component scanning to autodetect beans.
Makes it clearer that a specific method is to be used for initialisation. Intent is closer to the code.
Cons:
Initialisation no longer centrally specified in configuration.
You must remember to turn on annotation processing (which can sometimes be forgotten)
Have you tried implementing InitializingBean? It sounds like exactly what you're after.
The downside is that your bean becomes Spring-aware, but in most applications that's not so bad.
You could deploy a custom BeanPostProcessor in your application context to do it. Or if you don't mind implementing a Spring interface in your bean, you could use the InitializingBean interface or the "init-method" directive (same link).
To further clear any confusion about the two approach i.e use of
#PostConstruct and
init-method="init"
From personal experience, I realized that using (1) only works in a servlet container, while (2) works in any environment, even in desktop applications. So, if you would be using Spring in a standalone application, you would have to use (2) to carry out that "call this method after initialization.