Spring interface loading - spring

i'm wondering if spring loads an interface when declared as an #autowired attribute of an implementation class without having annotated the interface as a #component .
let me describe my problem a bit more :
i have both an interface and its implementation class have the same name but they reside in different packages . i annotated the implementation as #Component("myImplementation") .
but i end up having an exception that says :
conflicts with existing, non-compatible bean definition of same name and class
i'm thinking of excluding interfaces from <context:component-scan , what do you think ?
PS : my interface isn't #Component annotated , the application runs just fine on developpement environement , i only get the error after Proguard obfuscation

Your proguard.conf should be contain:
## ... preserve class annontation (Java EE 1.6 DI)
# Spring3
#-keep #org.springframework.stereotype.Service class *
-keep #org.springframework.stereotype.Controller class *
#-keep #org.springframework.stereotype.Component class *
#-keep #org.springframework.stereotype.Repository class *
proguard forums has more detailed answers.

Annotating your implementation with #Component and not annotating your interface is usually the right way to set things up. Spring's auto-wiring will look for a managed bean of a matching type, and your implementation will match for a field typed to the interface. If your interface is not annotated with #Component, or any Spring stereotype annotation, it should not be loaded into the context during a component scan. So, you should not have a problem if the interface and implementation have the same class name.
Are you sure you've tried not annotating the interface? Are you sure you don't have some other class somewhere else in your project that also has the same name as the interface and its implementation?

Well I think moving interfaces in different package would work because you would create object reference of interface and respective implementation beans would be auto wired to those object references. But you should follow naming conventions. There would be problem when differentiating interfaces and implementation classes as names are same. Follow standards like
interface SomeInterface {
//....
}
for implementation class of SomeInterface
class SomeInterfaceImpl implements SomeInterface {
// implementation....
}

Related

kotlin sealed class with Spring #Component

I am relatively new to kotlin but already loving it. In one of our projects, we use kotlin; when I tried to annotate a sealed class with Spring's #Component, the compiler threw the following exception,
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ShutDownManager' available
The simple shutdown manager class
package com.tes.streamconsumer.stream.processor
#Component
sealed class ShutDownManager(
#Autowired private val applicationContext: ApplicationContext
) {
fun shutDownApplication() {
SpringApplication.exit(applicationContext)
}
}
That is Autowired in another class,
package com.tes.streamconsumer.stream.processor
#Component
class AccountFacade(
#Autowired private val shutDownManager: ShutDownManager
) {
}
From the Kotlin documentation on sealed class, I understand this is useful to have restricted class hierarchies that provide more control over inheritance, so my questions below,
Is the sealed class not meant to be used with spring injection
or the ApplicationContext not ready hence the bean was not created?
Please shed light on what I miss here; thanks.
Your problem is nothing to do with the sealed class but elsewhere. Typically this kind of error occurs because Spring is not scanning your code looking for Beans in the way you expect.
You have correctly annotated your ShutDownManager class with #Component but you don't give enough information on your package structure.
This is the right kind of package structure for a Spring project:
com.mydomain.myapp
.facades
.AccountFacade.kt
.managers
.ShutDownManager.kt
.MyApp.kt
What is important is the Spring entrypoint class is higher than all the packages where you declare your Beans. The default behaviour of Spring is to Scan the packages below looking for Components/Services/etc. (You can override the behaviour to scan packages, etc explicitly, but my general preference is to locate the entry point for your application at the top of the tree on its own so it is easy to find in the tree structure and then everything beneath.)
One other word of caution is that in Java the package structure is intrinsically linked to the file system folder structure - you must keep them matched. There is no such restriction in Kotlin. I recommend not making use of this, since many Java devs will use the folder structure and never notice the package declaration differs; this could also be the source of Spring not finding your Beans.
Use of sealed classes/interfaces
I guess you might be thinking of using sealed to protect your ShutDownManager from being subclassed or overriden, but actually by default Kotlin makes all classes final. (You have to explicitly permit subclassing using the open keyword.)
sealed classes have some specific benefits in other places - most often when you are creating data objects, say Apple and Pear that implement/extend from Fruit. You can then write code that knows that there can only be two fruits if you had said sealed class Fruit. In Kotlin there is a when statement that's like Java's switch...case, and the compiler would know there is no need for an else if you were using a sealed Fruit class. See this article:
https://commonsware.com/Kotlin/pages/chap-sealed-002.html

Java Configuration vs Component Scan Annotations

Java configuration allows us to manage bean creation within a configuration file. Annotated #Component, #Service classes used with component scanning does the same. However, I'm concerned about using these two mechanisms at the same time.
Should Java configuration and annotated component scans be avoided in the same project? I ask because the result is unclear in the following scenario:
#Configuration
public class MyConfig {
#Bean
public Foo foo() {
return new Foo(500);
}
}
...
#Component
public class Foo {
private int value;
public Foo() {
}
public Foo(int value) {
this.value = value;
}
}
...
public class Consumer {
#Autowired
Foo foo;
...
}
So, in the above situation, will the Consumer get a Foo instance with a 500 value or 0 value? I've tested locally and it appears that the Java configured Foo (with value 500) is created consistently. However, I'm concerned that my testing isn't thorough enough to be conclusive.
What is the real answer? Using both Java config and component scanning on #Component beans of the same type seems like a bad thing.
I think your concern is more like raised by the following use case:
You have a custom spring-starter-library that have its own #Configuration classes and #Bean definitions, BUT if you have #Component/#Service in this library, you will need to explicitly #ComponentScan these packages from your service, since the default #ComponentScan (see #SpringBootApplication) will perform component scanning from the main class, to all sub-packages of your app, BUT not the packages inside the external library. For that purpose, you only need to have #Bean definitions in your external library, and to inject these external configurations via #EnableSomething annotation used on your app's main class (using #Import(YourConfigurationAnnotatedClass.class) OR via using spring.factories in case you always need the external configuration to be used/injected.
Of course, you CAN have #Components in this library, but the explicit usage of #ComponentScan annotation may lead to unintended behaviour in some cases, so I would recommend to avoid that.
So, to answer your question -> You can have both approaches of defining beans, only if they're inside your app, but bean definitions outside your app (e.g. library) should be explicitly defined with #Bean inside a #Configuration class.
It is perfectly valid to have Java configuration and annotated component scans in the same project because they server different purposes.
#Component (#Service,#Repository etc) are used to auto-detect and auto-configure beans.
#Bean annotation is used to explicitly declare a single bean, instead of letting Spring do it automatically.
You can do the following with #Bean. But, this is not possible with #Component
#Bean
public MyService myService(boolean someCondition) {
if(someCondition) {
return new MyServiceImpl1();
}else{
return new MyServiceImpl2();
}
}
Haven't really faced a situation where both Java config and component scanning on the bean of the same type were required.
As per the spring documentation,
To declare a bean, simply annotate a method with the #Bean annotation.
When JavaConfig encounters such a method, it will execute that method
and register the return value as a bean within a BeanFactory. By
default, the bean name will be the same as the method name
So, As per this, it is returning the correct Foo (with value 500).
In general, there is nothing wrong with component scanning and explicit bean definitions in the same application context. I tend to use component scanning where possible, and create the few beans that need more setup with #Bean methods.
There is no upside to include classes in the component scan when you create beans of their type explicitly. Component scanning can easily be targeted at certain classes and packages. If you design your packages accordingly, you can component scan only the packages without "special" bean classes (or else use more advanced filters on scanning).
In a quick look I didn't find any clear information about bean definition precedence in such a case. Typically there is a deterministic and fairly stable order in which these are processed, but if it is not documented it maybe could change in some future Spring version.

What is the difference between "constructor based injection" and " autowire by constructor mode" in Spring

I know and understand constructor based injection. But, the autowiring modes confuse me.
1) I have read that default mode for autowiring is 'no autowiring' i.e. We have to manually set the properties in xml file. But, isn't xml based configuration a type of autowiring? How can it be considered 'No autowiring'?
2) Other modes for autowiring are i) byName ii) byType iii)constructor iv) auto-detect. Am i correct to assume the following:
a) When using xml configuration based autowiring, the default mode is 'byName'(i.e. I have to keep the name of property reference the same as the name of the bean which is being used as a property.)
b) When using Annotations, default mode is 'byType'( Regardless of the place the #Autowired keyword is placed i.e on the setter, on the constructor or on the property, it will search the type of the property being autowried)
3) What is the difference between constructor based injection and 'constructor' mode of autowiring?(I have read that constructor mode means it applies byType mode on all the constructor arguments, but how is it different from placing #Autowired keyword on the constructor)
4) I know that to enable autowired mode byName in annotations, in the bean definition in the xml file, I have to use " autowire = 'byName' ". But, suppose I am using Annotations only config( using #Component, and no bean definitions in the xml ), and I want to use byName autowire mode, then what is the way of doing that?
I think you are a bit confused. First, you need to understand dependency injection (see here). There is ton of info about DI but in short, it means some third party (e.g spring IOC) passes the dependencies to the objects rather than the objects to create/obtain the references themselves. This could happen either through constructor or setter. For instance, consider constructor DI
class B{
}
class A{
private B b;
public A(B b){
this.b = b;
}
}
Some third party will inject an instance of class B into A rather class A create a reference to B itself. Very often you would use an interface so class A wouldn't even know what object will be injected into it.
Now in Spring there are different ways to configure these associations between the objects (the example above). You can either use XML, Java Config or Autowiring. They are independent but do the same stuff.
In both XML and JAVA config you need to configure the dependencies explicitly - either in xml file or having a #Configuration class for the JAVA Config and annotating the beans with #Bean. The autowiring is different. There you create simple POJOs which you annotate with #Component, #Controller, #Service or #Repository. They will be automatically registered as beans via component scanning. With autowiring you don't need to explicitly configure the dependencies in XML file or JAVA Config class. You can do it in code directly. For instance, if we have to compare java config vs autowiring using the previous example
Java Config (explicit config in a config class)
#Bean
public A getA(){
return new A(new B());
}
Autowiring (implicit - done in code)
#Component
class B{
}
#Component
class A{
private B b;
#Autowired
public A(B b){
this.b = b;
}
}
In the latter we autowire class B into class A (they both will be registered as beans due to #Component annotation) without having explicitly defined this association in an xml file or java config class. I hope it makes sense.
If you have to specify the bean names in the xml, its not happening automatically, hence its not autowiring.
With autowiring spring will figure out what bean to inject even though it may not be explicitly written.
When using xml configuration based autowiring, the default mode is 'byName'
When using Annotations, the ordering that happens depends on the annotation used as there are a few that can be used. #Autowire #Resource #Inject.
When using #Component, the default wiring is of type. The method below will resolve on any autowiring needs for a Service object.
#Bean
public Service getMyService(){
return new Service();
}
If there are multiple #Bean methods that return a Service you will get an error.
If you wanted to do wire via name while using #Component you would add the #Qualifier("nameToUse") annotation to the variable. It would find an #Bean annotated method called getNameToUse().
#Autowired
#Qualifier("nameToUse")
private Service myService;

Does Spring #transaction work on a concrete method of abstract class

From spring reference doc
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the #Transactional annotation, as opposed to annotating interfaces. You certainly can place the #Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java
annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.
Though it only talks about interfaces, abstract classes are considered as non-concrete as well.
So if i have an abstract class
public abstract class BaseService{
//here is a concrete method
#Transactional
public void updateData{
//do stuff using dao layer
}
and a concrete class which extends the class
public class SpecialService extends BaseService{
//body of class
}
Now if i call specialService.updateData() from my controller class will it be transactional?
Granting that you have actually configured Spring transaction management correctly, using #Transactional on an abstract superclass will work, since #Transactional is itself annotated with #Inherited and from it's Javadoc we have:
Indicates that an annotation type is automatically inherited. If an
Inherited meta-annotation is present on an annotation type
declaration, and the user queries the annotation type on a class
declaration, and the class declaration has no annotation for this
type, then the class's superclass will automatically be queried for
the annotation type. This process will be repeated until an annotation
for this type is found, or the top of the class hierarchy (Object) is
reached. If no superclass has an annotation for this type, then the
query will indicate that the class in question has no such annotation.
Note that this meta-annotation type has no effect if the annotated
type is used to annotate anything other than a class. Note also that
this meta-annotation only causes annotations to be inherited from
superclasses; annotations on implemented interfaces have no effect.
To actually see that #Transactional is annotated with #Inherited check out it's Javadoc

how to implement Factory Pattern with Spring 3.0 Services

In my project I have an interface annotated with org.springframework.stereotype.Service tag.
I have two different implementation for this interface.
In my manage bean, I am injecting interface Service class and using its methods.
Now my requirement is, in run time I have to pick particular implementation (lets say based on login user group) so that respective logic can be invoked.
As per my understanding, we can achieve this using Factory pattern in java and achieve the same.
How can we implement this in SPRIng???
Besides suggested related topic above, there is a good thread on JavaRanch.
You can use
#Qualifier("myServiceImpl1") annotation together with #Autowired. In
that case this particular implementation of the interface will be
injected. You should also use the same name with your #Component,
#Service or #Repository annotations e.g.
#Service("myServiceImpl1")
public class MyServiceImpl1 implements MyService{}
public class Consumer{
#Autowired
#Qualifier("myServiceImpl1")
public MyService myServiceImpl1;
}
#Primary together with #Component, #Service or #Repository
annotations in your implementation class, in that case this
implementation will be injected by default.
If you mark a list of some interface type with #Autowired, all
available implementations of this interface will be injected.
#Autowired
public List<MyService> allAvailableImplementations;

Resources