object creation in spring - spring

If I am using spring frame work in my application does creating an object like this Test test = new Test() a bad way for creating an instance? Should I always use the bean config to get the objects/bean that I need? If yes, does that means I should have all the object/bean definition in spring applicationContext xml file?

If you want your object to be managed by Spring (this means that dependencies are injected, among other things) you have to use the ApplicationContext.
Calling Test test = new Test() isn't illegal, or even bad practice. It just means that Spring will have no awareness of this object, and it won't bother autowiring it's dependencies, or doing anything else that you'd expect Spring to do.
You don't necessarily need to use the applicationContext.xml file for ALL of your bean declarations. Many people favor annotations, which allow you to declare beans outside of the applicationContext.xml file.
It's worth nothing that Spring-managed beans are by default singletons (think of Servlets). If you want stateful beans that are Spring aware, you could use an ObjectFactoryCreatingFactoryBean to do something like this:
#Autowired
private ObjectFactory myWidgetFactory;
public void doStuff() {
Widget w = myWidgetFactory.getObject();
}
You can read more about this behaviour here:
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBean.html

For me there's a big difference between objects that represent components of my application -- services, controllers, DAOs, utilities, etc. -- and objects that represent entities within my application -- Person, Order, Invoice, Account, etc. The former type of objects should absolutely be managed by Spring and injected. The latter type are typically created on the fly by the application, and that frequently will involve calling new. This is not a problem.

Test test = new Test() a bad way for
creating an instance?
Yes it is bad practice.
Should I always use the bean config
to get the objects/bean that I need?
Yes, if you are using Spring for dependency injection.
If yes, does that means I should have
all the object/bean definition in
spring applicationContext xml file?
Always! You could use Annotations too.

Related

Initialise autowired service in spring boot

I am running 100 JUnit tests with a single autowired service. I have a service named createArray this service adds values in the ArrayList.
The problem is the values persist in the array list. When a new test case runs it adds its own value to the array.
I want to clear the autowired creatArray object whenever new test case runs.
Spring beans by default are singleton, this is why this is happening.
In order to have a different behaviour you should check the different "bean scope".
This is a quick explanation of it:
https://www.tutorialspoint.com/spring/spring_bean_scopes.htm
I believe that if you use the prototype scope ( as per this tutorial ) you might end up with the solution you want.
Regarding how to do this, it really depends if your beans are defined by xml or annotation.
You can check google a lot of examples.
In case you using XML it should be easy, on the bean add the "scope=prototype".
For annotation use under #Bean the annotation #Scope("prototype")

Why use spring beans instead of object initialization

I am trying to understand the idea of spring beans and why I should use them. If I create a bean and use it to print something out like this.
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Account acc = (Account)context.getBean("account");
acc.printAccName();
Why not just create an object of that class like this
Account acc2 = new Account();
acc.printAccName();
I have been watching some video's and did some reading but I did not get an answer why it is better.
Usually what you inject is business logic or services which typically is what changes in a system.
You are trying to inject a domain object Account these objects are not subject to change so it is okay to create the object via new. Perhaps, this is what it is confusing you.
The idea, is to let the container handle the instantiation of your logic or services that change regularly so you can swap them easily without having to open the client classes, because these might be already in production, tested and a developer could potentially introduce new bugs and break things. One way to avoid this is to follow a principle called Open-Closed principle. Then you code to abstractions so you can easily inject concrete implementations via dependency injection.
Imagine the following escenario. For a bookstore, you have different implementations of how to save a book into a database e.g. using JDBC BookServiceJDBCImpl, or using an ORM BookServiceHibernateImpl etc..
// Create & get the Spring container, where you configure your implementations
// e.g. bookServiceJDBC, or bookServiceHibernate
ApplicationContext container = new ClassPathXmlApplicationContext("spring-config.xml");
// the container loads the appropriate bean say bookServiceHibernate
BookService bookService = (BookService) container.getBean("bookService");
//Create a new book this is a domain object usually you use new
Book newBook = new Book("1234", "Spring in Action","Rod Johnson");
//Now save the book using the implementation defined in the
//container
bookService.registerNewBook(newBook);
This is how part of the container file may look like, in here you define the concrete implementation:
<bean id="bookService" class="service.BookServiceHibernateImpl"/>
By letting the container handle this you could inject different implementations without having to touch the client class or even knowing which implementation will be passed.
Check this Dependency Injection blog post it explains a way to achieve it using Spring.
Bare in mind that in Spring you can use java annotations or xml, and that there are different ways to inject dependencies e.g. via get/set, constructors etc this is just an illustrative example of the general DI concept. The design is up to the developer.
Another reason why you would use beans is to aid testing.
We also extract the RestTemplate into a #Bean to make it easier to
test (it can be mocked more easily that way). Link

Object created in Spring

I would like to know, whether this is a valid practice to use "new" in spring to create a Object?
You can either use xml->bean to create a object using xml file or use annotations to create a object.
This question arises when I am working on a project and where I want to create a object of a property class(which contains properties and setter/getter method of those properties).
I am able to create a object using new and its working fine but if spring has capability to create and manage object lifecycle then which way I need to go create a object and why?
I think the confusion may arise because of the (over)usage of spring as DI mechanism. Spring is a framework providing many services. Bean or dependency injection is just on of those.
I would say that for POJOs which have just setter and getters without much logic in them you can safely create objects using new keyword. For example, in case of value objects and data classes which do not have much configuration or life cycle events to worry about, go ahead and crate those using new keyword. If you repetitively create these objects and have fields which are not changing often, then I would use spring because it will lessen some of the repetitive code and object creation can be considered externalized or separated from your object usage.
Classes instantiated using spring bean definition xml/annotations are basically 'Spring-Managed' beans which mostly means that their life cycle, scope, etc are managed by spring. Spring manages objects which are beans, which may have some life cycle methods and APIs. These beans are dependencies for the classes in which the are set. The parent objects call some API of these dependencies to fulfil some business cases.
Hope this helps.
The Dependency Injection concept in spring is more useful when we need to construct an object that depends upon many objects, because it saves you time and effort for constructing as well as instantiating dependent objects.
In your case , Since it's a POJO class with only setters and getters , I think it is absolutely safe to instantiate it using a new keyword.

abount the singleton beans of spring

I am reading the 《Spring in Action》, and it says "singleton beans in Spring often don't maintain state because they're usually shared among multiple threads", but in my opinion, a bean in Spring is a POJO, so how can it not maintain state?
I am reading the 《Spring in Action》, and it says "singleton beans in
Spring often don't maintain state because they're usually shared among
multiple threads", but in my opinion, a bean in Spring is a POJO, so
how can it not maintain state?
Yes, it's better for a Spring/Singleton to not have a state (of course it can uses other Spring/Singletons [also them without a state]) so you can call its methods from different threads without worring about they could messed up its state (it doesn't have one :-)).
Let's think about a calculator that stores its intermediate results inside an internal stack, what can happen if two threads try to calculate something at the same time?
A Spring/Singleton is annotated (and if it's not it's just like it would be) and lives inside the spring context , it's not a POJO.
If you want to have a Spring/Bean with a state you have to use the scope "prototype", with this kind of scope every time you get a bean you will get a difference instance.
Sorry for the bad english
The book is implying that the state of a bean may not be trustworthy at a given point in time due to manipulation of its state by another thread. If multiple threads are accessing the same instance of a bean you cannot be sure of what state changes have occurred on the bean prior to using it. Since Spring uses Singletons by default there is only one instance of a bean. If multiple threads hit the bean at the same time there could be issues with the state of the bean.
So your correct that the beans will maintain state, however the state may be unreliable due to modifications from other threads.
In a typical web application, you have multiple threads (one per request) and all the requests are using the same beans. In a typical layered application, they will uses a Controller which uses then a Service which uses then a Repository. All of these beans should be singletons without any state. Otherwise you will have bugs due to concurrency (e.g. one thread modifies data in a singleton while another thread do the same).
I think that your misunderstanding comes from saying that bean in Spring are POJO. Most of Spring beans are stateless beans which I would not describe as POJO.
A Spring bean is considered a POJO in the sense that it does not need to adhere to special requirements (implement certain interfaces, extend particular class, be specific in some way, etc.) to be used with Spring.
Depending on the requirements a Spring bean might need to maintain, and operate on, its state.
It also depends on the requirements to consider if the Spring bean should be a singleton or not.
If a singleton Spring bean is maintaining its own state, proper safeguards must be taken to ensure correct concurrent access/modification.
Confusion comes from a general pattern used in enterprise applications where Spring beans are used to implement bulk of the system logic, and support operations.
In these scenarios, generally its a good practice to not have any state in the Spring bean itself, and just be an extension of the Value Object/Data Transfer Object that contain actual state.
Since these Spring beans are not going to maintain their own state, they are almost always created as singletons.
SomeClass, SomeOtherClass and Situation are all POJO in below code.
SomeClass and SomeOtherClass are Spring beans but Situation is not, which is a DTO.
class SomeClass {
private int x; // not restricted
public void handleSituation(Situation s) {
// may or may not use/modify SomeClass state represented by 'x'
// one approach is to provide all required information through parameters
}
}
class SomeOtherClass {
#Autowired
private SomeClass sc;
public void process() {
// gets called from another object
Situation z = new Situation();
sc.handleSituation(z);
// other processing
}
}
<!-- default scope = singleton -->
<bean id="someClassBean" class="SomeClass"/>
<bean id="someOtherClassBean" class="SomeOtherClass">
<property name="someClass" ref="someClassBean"/>
</bean>
This is a slight variation from pure OOP in which above would be coded similar to following.
class SomeOtherClass {
public void process() {
// gets called from another object
Situation z = new Situation();
z.handle();
// other processing
}
}

Spring beans redefinition in unit test environment

We are using Spring for my application purposes, and Spring Testing framework for unit tests. We have a small problem though: the application code loads a Spring application context from a list of locations (XML files) in the classpath. But when we run our unit tests, we want some of the Spring beans to be mocks instead of full-fledged implementation classes. Moreover, for some unit tests we want some beans to become mocks, while for other unit tests we want other beans to become mocks, as we are testing different layers of the application.
All this means I want to redefine specific beans of the application context and refresh the context when desired. While doing this, I want to redefine only a small portion of the beans located in one (or several) original XML beans definition file. I cannot find an easy way to do it. It's always regarded that Spring is a unit-testing-friendly framework, so I must be missing something here.
Do you have any ideas how to do it?
Thanks!
I would propose a custom TestClass and some easy rules for the locations of the spring bean.xml:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"classpath*:spring/*.xml",
"classpath*:spring/persistence/*.xml",
"classpath*:spring/mock/*.xml"})
#Transactional
#TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DirtiesContextTestExecutionListener.class})
public abstract class AbstractHibernateTests implements ApplicationContextAware {
/**
* Logger for Subclasses.
*/
protected final Logger log = LoggerFactory.getLogger(getClass());
/**
* The {#link ApplicationContext} that was injected into this test instance
* via {#link #setApplicationContext(ApplicationContext)}.
*/
protected ApplicationContext applicationContext;
/**
* Set the {#link ApplicationContext} to be used by this test instance,
* provided via {#link ApplicationContextAware} semantics.
*/
#Override
public final void setApplicationContext(
final ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
}
If there are mock-bean.xml in the specified location, they will override all "real" bean.xml files in the "normal" locations - your normal locations might differ.
But … I would never mix mock and non-mock beans, as it's hard to trace problems when the application grows older.
One of the reasons spring is described as test-friendly is because it may be easy to just new or mock stuff in the unit test.
Alternately we have used the following setup with great success, and I think it is quite close to what you want, I would strongly recommend it:
For all beans that need different implementations in different contexts, switch to annotation based wiring. You can leave the others as-is.
Implement the following set of annotations
<context:component-scan base-package="com.foobar">
<context:include-filter type="annotation" expression="com.foobar.annotations.StubRepository"/>
<context:include-filter type="annotation" expression="com.foobar.annotations.TestScopedComponent"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
Then you annotate your live implementations with #Repository, your stub implementations with #StubRepository, any code that should be present in the unit-test fixture ONLY with #TestScopedComponent. You may run into needing a couple more annotations, but these are a great start.
If you have a lot of spring.xml, you will probably need to make a few new spring xml files that basically only contain the component-scan definitions. You'd normally just append these files to your regular #ContextConfiguration list. The reason for this is because you frequently end up with different configurations of the context-scans (trust me, you will make at least 1 more annotations if you're doing web-tests, which makes for 4 relevant combinations)
Then you basically use the
#ContextConfiguration(locations = { "classpath:/path/to/root-config.xml" })
#RunWith(SpringJUnit4ClassRunner.class)
Note that this setup does not allow you to have alternating combinations of stub/live data. We tried this, and I think that resulted in a mess I wouldn't recommend anyone ;) We either wire inn the full set of stubs or the full set of live services.
We mainly use auto-wired stub dependencies when testing gui near stuff where the dependencies are usually quite substantial. In cleaner areas of the code we use more regular unit-testing.
In our system we have the following xml-files for component-scan:
for regular web production
for starting web with stubs only
for integration tests (in junit)
for unit tests (in junit)
for selenium web tests (in junit)
This means we totally have 5 different system-wide configurations that we can start the application with. Since we only use annotations, spring is fast enough to autowire even those unit tests we want wired. I know this is untraditional, but it's really great.
Out integration tests run with full live setup, and once or twice I have decided to get really pragmatic and want to have a 5 live wirings and a single mock:
public class HybridTest {
#Autowired
MyTestSubject myTestSubject;
#Test
public void testWith5LiveServicesAndOneMock(){
MyServiceLive service = myTestSubject.getMyService();
try {
MyService mock = EasyMock.create(...)
myTestSubject.setMyService( mock);
.. do funky test with lots of live but one mock object
} finally {
myTestSubject.setMyService( service);
}
}
}
I know the test purists are going to be all over me for this. But sometimes it's just a very pragmatic solution that turns out to be very elegant when the alternative would be really really ugly. Again it's usually in those gui-near areas.
See this tutorial with #InjectedMock annotation
It saved me a lot of time. You just use
#Mock
SomeClass mockedSomeClass
#InjectMock
ClassUsingSomeClass service
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
and all your problems are solved. Mockito will replace the spring dependency injection with a mock. I just used it myself and it works great.
There are some very complicated and powerful solutions listed here.
But there is a FAR, FAR simpler way to accomplish what Stas has asked, which doesn't involve modifying anything other than one line of code in the test method. It works for unit tests and Spring integration tests alike, for autowired dependencies, private and protected fields.
Here it is:
junitx.util.PrivateAccessor.setField(testSubject, "fieldName", mockObject);
You can also write your unit tests to not require any lookups at all:
#ContextConfiguration(locations = { "classpath:/path/to/test-config.xml" })
#RunWith(SpringJUnit4ClassRunner.class)
public class MyBeanTest {
#Autowired
private MyBean myBean; // the component under test
#Test
public void testMyBean() {
...
}
}
This gives an easy way to mix and match real config files with test config files.
For example, when using hibernate, I might have my sessionFactory bean in one config file (to be used in both the tests and the main app), and have by dataSource bean in another config file (one might use a DriverManagerDataSource to an in-memory db, the other might use a JNDI-lookup).
But, definitely take heed of #cletus's warning ;-)
Easy. You use a custom application context for your unit tests, or you don't use one at all and you manually create and inject your beans.
It sounds to me like your testing might be a bit too broad. Unit testing is about testing, well, units. A Spring bean is a pretty good example of a unit. You shouldn't need an entire application context for that. I find that if your unit testing is so high-level that you need hundreds of beans, database connections etc., you have a really fragile unit test that is going to break on the very next change, will be hard to maintain and really isn't adding a lot of value.
You can use the import feature in your test app context to load in the prod beans and override the ones you want. For example, my prod data source is usually acquired via JNDI lookup, but when I test I use a DriverManager data source so I don't have to start the app server to test.
I don't have the reputation points to pile on duffymo's answer, but I just wanted to chime in and say his was the "right" answer for me.
Instantiate a FileSystemXmlApplicationContext in your unit test's setup with a custom applicationContext.xml. In that custom xml, at the top, do an as duffymo indicates. Then declare your mock beans, non-JNDI data sources, etc, that will override the id's declared in the import.
Worked like a dream for me.
You do not need to use any test contexts (doesn't matter is XML or Java based). Since Spring boot 1.4 there is available new annotation #MockBean which introduced native support for mocking and Spying of Spring Beans.
Perhaps you could use qualifiers for your beans? You would redefine the beans you want to mock up in a separate application context and label them with a qualifier "test". In your unit tests, when wiring your beans always specify the qualifier "test" to use the mock ups.
I want to do the same thing, and we're finding it essential.
The current mechanism we use is fairly manual but it works.
Say for instance, you wish to mock out bean of type Y. What we do is every bean that has that dependency we make implement an interface - "IHasY". This interface is
interface IHasY {
public void setY(Y y);
}
Then in our test we call the util method...
public static void insertMock(Y y) {
Map invokers = BeanFactory.getInstance().getFactory("core").getBeansOfType(IHasY.class);
for (Iterator iterator = invokers.values().iterator(); iterator.hasNext();) {
IHasY invoker = (IHasY) iterator.next();
invoker.setY(y);
}
}
I do not want to create a whole xml file just to inject this new dependency and that is why I like this.
If you're willing to create an xml config file then the way to go would be to create a new factory with the mock beans and make your default factory a parent of this factory. Make sure then that you load all your beans from the new child factory. When doing this the sub-factory will override the beans in the parent factory when the bean id's are the same.
Now if, in my test, If I could programmatically create a factory, that would be awesome. Having to use xml is just too cumbersome. I'm looking to create that child factory with code. Then each test can configure its factory the way it wants. There's no reason why a factory like that won't work.
spring-reinject is designed to substitute beans with mocks.
Since the OP this has come along: Springockito

Resources