Spring finds a test class on a jar and I get a NoUniqueBeanDefinitionException - spring

I have a project that uses Spring. The project consists on two different parts, the generic part and the specific one. The generic part is compiled as a .jar, it defines a set of traits and it's used as a dependency by the specific part, which is the one that implements the methods.
In order to test the generic part, I have created a "fake" implementation of one of the trait (let's say "fakeMethodA"), under the test directory of the generic project and I annotated this fake implementation with the #Component annotation. I'm getting the beans using the application context.
The problem comes when I try to use this generic part on the specific project. Since my actual implementation of this trait (let's say "methodAImplementation") also has a #Component annotation, when I run my tests I get:
org.springframework.beans.factory.NoUniqueBeanDefinitionException
expected single matching bean but found 2:
It finds the fakeMethodA from the generic part and methodAImplementation from the implementation. Is there any way to exclude this "fake" implementation from the execution? Is there a better way to define this?
Any help would be greatly appreciated.

The problem was solved by the use of #Profile annotation on the generic method.
I annotated the fake method on the tests with:
#Profile(value = Array("Test"))
And the right implementation with another profile value. After that, when I select the bean from the context, I can select the correct profile.

Related

How to use AOP annotation inside method not in method level

I am using Spring AOP to log the DB execution time, but it is applying to the entire method execution time.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface TrackExecutionTime {
}
Is there any possibility that we can use this #TrackExecutionTime not in the method level but inside a method just above some statement like below -
#TrackExecutionTime
List<Release> releaseList = releaseRepo.findByProductName(productName.toUpperCase());
that way I can able to get only the DB execution time not only the entire method execution time, as my method contains other business logic too which also including if we use the AOP annotation at the method level.
Your question is not AOP-specific, because annotations are a Java language feature. The answer is: Annotations on arbitrary lines of code are not part of the Java language concept, which for you means you also cannot use them for AOP purposes. This is simply a Java limitation. Neither Spring AOP nor native AspectJ can support a feature which does not exist in Java to begin with.
Friendly suggestion: Please learn more about Java first, then get acquainted with some basic software design and clean code principles. Finally, you shall be able to achieve what you want, albeit in a different way from what you just dreamed up here.
Spring AOP default configuration uses proxies to execute the aspect hence only methods can be annotated.
A bit of a detour on the proxies. A proxy wraps a target method so when you call a method elsewhere Spring makes sure to invoke the method on the proxy and that invocation then contains the aspect code which gets executed before, after, around the call itself (depending on the aspect). There can be several proxies wrapping a single class.
Then an option is to add your aspect annotation to the repository method.
If we need to track the execution time only for subset of calls to the method (which sounds a bit strange a requirement) then we can add a wrapper method - say make a Spring-managed Metrics class with a said time tracking method that accepts a lambda and is annotated with the #TrackExecutionTime. The original call would then be something like
metrics.executeTimed(() -> releaseRepo.findByProductName(productName.toUpperCase()));

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.

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

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.

Why to use #Autowired on class in Spring

I read about the advantages of using Dependency for interface.
I understand the concept for interface - but why to use #Autowire on class? If we use Autowire on class I know in advance what is the implmeneted class and it's like a regular member of it (without the ability of get to this member)!
What am I missing?
1) Convenience - you do not need to take care for initializing your components, you save time on typing code and configuration files,
2) Forcing good practices - your components to be autowired must be written to be manageable by Spring and spring will take care about error checking for you and pop all errors. So your code will be organized in component collaborating way.
3) Autowiring will also reduce your effort when your classes/beans will grow and evolve.
If you use #Autowire and not call the constructor, you mark the class to be dynamically initialized by the Spring Container. This allows you to set class properties as defined in your spring configuration.
If we use Autowire on class I know in
advance what is the implmeneted class
and it's like a regular member of it
When you wire the dependency through XML instead of Annotations, you also know in advance in which class are you going to inject it.
But You still declare an Interface as dependency, so you can wire any Implementation of this interface at runtime.

Resources