Initialise autowired service in spring boot - spring

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")

Related

Spring Boot : how auto configure works and #JsonTest

I've read some stuff about how auto-configuration works behind the scene (configuration classes with #Conditional, spring.factories inside /META-INF etc...)
Now I'm trying to understand with an example : #JsonTest
I can see this annotation is annotated with things like #AutoConfigureJson
What this #AutoConfigureJson does exactly ? Does it import some configuration classes with beans inside ? How Spring know how to use this annotation (basically this annotation is almost empty and doesn't say which classes to scan)
#AutoConfigure... (like #AutoConfigureJson) annotations are the way to allow tests with multiple "slices".
Slices load into your tests only a subset of the application, making them run faster. Let's say you need to test a component that uses the Jackson Object Mapper, then you would need the #JsonTest slice. (here is the list of all available slices.)
But you may also need some other part of the framework in your test not just tha single slice; let's say the JPA layer. You may want to annotate the test with both #JsonTest and #DataJpaTest to load both slices. According to the docs, this is not supported.
What you should do instead is choose one of the#...Test annotation, and include the other with an #AutoConfigure... annotation.
#JsonTest
#AutoConfigureDataJpa
class MyTests {
// tests
}
Update:
at a certain point while evaluating the annotation, Spring Boot will hit this line and will pass to the method SpringFactoriesLoader.loadFactoryNames() a source, that is the fully qualified name of the annotation (like interface org.springframework.boot.test.autoconfigure.json.AutoConfigureJson for example).
The loadFactoryNames method will do its magic and read the necessary information from here.
If more details are needed, the best thing is to use a debugger and just follow along all the steps.

Use of #Scope annotation with Spring Controller

I am working on a project which is based on Struts 1.x, converting it to Spring 4. I have visited many tutorial sites and read Spring 4 tutorials but no one used #Scope annotation with #Controller in tutorial application. My Question is :
1) Is it compulsory to use #Scope attribute?
2) What if we do not use?
3) Is it good practice to use #Scope with #Controller?
We have also reading a property file at server start up and storing it into Property class. I am reading some property in DAOImpl class(Annotated as #Repository). If I use #Scope attribute with both Controller and Repository then it return value otherwise it return NullPointerException. Why is this behavior?
1) Is it compulsory to use #Scope attribute?
No. If you want the default ("singleton") then you don't need to specify.
2) What if we do not use?
Then your application will only create one instance of the bean.
3) Is it good practice to use #Scope with #Controller?
No. It does not make sense for an application to have more than one instance of a controller class (or a repository). If you have a need to use both annotations together, then you are not modelling your classes very well.
Why is this behavior?
Because the context cannot create a scoped bean to inject if the target bean is not being constructed in that scope (e.g. trying to inject a request-scoped bean into a bean that's being created outside the context of a request).
To solve this you need to use scoped-proxies, by setting proxyMode.
In your specific case, however, the solution is that you don't actually need non-default scope.
#Scope- Isn't Compulsory to use with #Controller, unless and until u need one based on your requirements. #Scope defines the scope of the bean, by default its singleton.
And also, Property Class should be managed by Spring, otherwise it will give you an exception.

Practical use of ApplicationContextAware in spring

I have had chance of working on only one project using spring , and the way it worked was
Make a singleton class (lets say MySpringHelper), that has method like getBean(String beanName)
What getBean(String) does is, it first checks existence of applicationContext, if it exists uses same to get the bean , else creates new applicationContext and returns the bean
Wherever in you project you need a bean simply call MySpringHelper.getBean("abc")
Keeping this in mind , when i was studying spring , i noticed interface "ApplicationContextAware" ... I am not sure when will this be needed, uses above pattern such interface seems not of any use. Or the above Singleton MySpringHelper pattern/approach is incorrect ??
Looking forward to learn from your experience
To give more details on application , its like a pdf file generator, 1 pdf file having 12-15 different charts, so the main method runs 1 thread for each chart , and inside these chart logic we are using singleton MySpringHelper
Why are you checking the existance of applicationContext? It should be there if your helper bean is configured in xml and has setter method in it. There is no need to create application context in that case.
For your case, I would suggest you get applicationContext injected by Spring rather than by using ApplicationContextAware.

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

object creation in 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.

Resources