What are possible causes for Spring #ComponentScan being unable to auto create a class anotated by #Repository - spring

I came across a tutorial which seemed to be fitting my usecase and tried implementing it. I failed but wasn't sure why. So I tried to find another example with similar code and looked at the book "Spring in Action, Fourth Edition by Craig Walls"
The books describes at page 300 the same basic approach. Define a JdbcTemplate Bean first.
#Bean
NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
return new NamedParameterJdbcTemplate(dataSource);
}
Then a Repository implementing an Interface
#Repository
public class CustomRepositoryImpl implements CustomRepository {
private final NamedParameterJdbcOperations jdbcOperations;
private static final String TEST_STRING = "";
#Autowired
public CustomRepositoryImpl(NamedParameterJdbcOperations jdbcOperations) {
this.jdbcOperations = jdbcOperations;
}
So I did like the example in the book suggests, wrote a test but got the error message
Error creating bean with name 'de.myproject.config.SpringJPAPerformanceConfigTest': Unsatisfied dependency expressed through field 'abc'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'de.myproject.CustomRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
To my understanding as book and tutorial describe, the Repository should be recognized as a Bean definition by the component scan.
To test this I created an context and asked for all registered Beans.
AnnotationConfigApplicationContext
context = new AnnotationConfigApplicationContext();
context.getBeanDefinitionNames()
As assumed my Repository wasn't among them. So I increased, for test purposes only, scope of the search in my project, and set it to the base package. Every other Bean was shown, except the Repository.
As an alternative to component scanning and autowiring, the books describes the possibility to simply declare the Repository as a Bean, which I did.
#Bean
public CustomRepository(NamedParameterJdbcOperations jdbcOperations) {
return new CustomRepositoryImpl(jdbcOperations);
}
After that Spring was able to wire the Repository. I looked at the github code of the book in hope for a better understanding, but unfortunately only the Bean solution, which runs, is implemented there.
So here are my questions:
1.) what possible reasons are there for a Bean definition, is a scenario like this one, not to be recognized by the component scan?
2.) this project already uses Spring JPA Data Repositories, are there any reasons not to use both approaches at the same time?

The problem is naming of your classes. There are many things to understand here.
You define a repository Interface #Repository is optional provided it extends CRUDRepository or one of the repositories provided by spring-data. In this class you can declare methods(find By....). And spring-data will formulate the query based on the underlying database. You can also specify your query using #Query.
Suppose you have a method which involves complex query or something which spring-data cannot do out of the box, in such case we can use the underlying template class for example JdbcTemplate or MongoTemplate..
The procedure to do this is to create another interface and a Impl class. The naming of this interface should be exactly like Custom and your Impl class should be named Impl.. And all should be in same package.
For example if your Repository name is AbcRepository then Your custom repository should be named AbcRepositoryCustom and the implementation should be named AbcRepositoryImpl.. AbcRepository extends AbcRepositoryCustom(and also other spring-data Repositories). And AbcRepositoryImpl implements AbcRepositoryCustom

I was able to "solve" the problem myself.
As we also have a front end class annotated with the same basePackage for the #ComponentScan
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = {"de.myproject.*"})
so there were actually two identical #ComponentScans annotations which I wasn't aware off and this did lead to a conflict. It seams the ordering how the whole application had to be loaded had changed, but thats only me guessing.
I simply moved my Repository and its Impl to a subpackage, and changed the
#ComponentScan(basePackages = {"de.myproject.subpackage.*"})
and now everything works fine. Though it escapes me, what the exact reason behind this behavior is.

Related

Is it still loose coupling if we use #qualifier

we use interface for autowiring service into controller
this is for loose coupling , coz the interface can hold object of any of its implementations. so no need to write the implementation name and create tight coupling.
however when we have more than one implementations for an interface, we write the #qualifier .
my question is if we have to write qualifier to tell which implementation needs to be injected, then should we still call it loose coupling??
class ServiceInterface {
interfaceMethod();
}
implementation 1:
#component("service1")
class ServiceImpl1 implements ServiceInterface {
interfacemethod(){
}
}
implementation 2:
#component("service2")
class ServiceImpl2 implements ServiceInterface {
interfaceMethod(){
}
now only instead of directly creating Object of ServiceImpl1() using new
ServiceImpl1 obj = new ServiceImpl1();
we write in
class Controller {
#autowired
#qualifier("service1")
ServiceInterface se;
sc.interfaceMethod();
}
Partially yes, because the component that uses the injected qualified bean still didn't create it or handle its lifecycle.
But indeed using #Qualifier creates some sort of coupling. If you want to avoid this, consider making one of your ServiceInterface beans the primary implementation for the interface annotating its class with #Primary as follows:
#Component
#Primary
class ServiceImpl1 implements ServiceInterface {
interfacemethod(){
}
}
With this, every time you need a ServiceInterface implementation but you don't actually specify which one you want (using #Qualifier) the primary one is injected by Spring.
Even though you are using the #Qualifier annotation you are still using inversion of control to let the framework manage your dependencies.
Furthermore, lets say you wouldn't autowire this implementation but use 'new' to create your object.
When the implementation changes you would need to update all the places where this is created. However, with dependency injection you wouldn't need to do so. Therefore you still have the advantages of dependency injection with regards to loose coupling.
If you would like to have your implementation less coupled with your target class then you could do a few things
Use #Primary for a bean to determine the default implementation.
Autowire your implementations into a List<ServiceInterface>
Use Spring's ObjectFactory to determine which bean to use at runtime
Use Profiles to determine which bean to autowire

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.

How to inject Spring's Validator implementation?

I started with generating my application using JHipster v.3.5.1.
After some time, I needed to create validator to perform some business logic validation on my entity, when it is created with POST. So I made:
#Component
public class MyValidator implements Validator
Then, I tried to inject it into my controller (annotated with #RestController), but no matter which way I tried, it always resulted in something like that:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.my.app.service.domain.MyValidator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Ways I tried to create bean and inject it
#Autowired
private MyValidator myValidator;
#Inject
private MyValidator myValidator;
#Autowired
#Qualifier("myValidator")
private MyValidator myValidator; (with #Component("myValidator") on class)
#Inject
#Qualifier("myValidator")
private MyValidator myValidator; (with #Component("myValidator") on class)
//Below was inserted in class annotated with #Configuration
#Bean
public MyValidator myValidator() {
return new MyValidator();
}
However I tried it - it failed. I always got NoSuchBeanDefinitionException or field value was set to null.
I've also checked class location in project structure. To be 100% percent sure it's well placed, I've put it in package the with #Services, which are scanned and work well. No effect.
I know that it seems to be pretty easy task and I know this injection is possible (I've seen it done in project in my work), but somehow I'm not able to make it work in my project.
Maybe I'm missing something in configuration? Thanks for any help :)
I believe your issue is that when you use #Autowired inside a class annotated with #Configuration you are just referencing to a bean that is defined in a separate configuration file, that is it has to be declared in another file also with the #Configuration annotation.
If you want to refer refer to another implicit bean such as your validator annotated with #Component you will need to do it in another implicit bean also annotated to with implicit notation such as #Component, #Service, #Controller, etc
The #Autowired alone should work unless you have more than one class implementing the same interface. That is when you will need to use the #Qualifier.

What is the difference between dependency injection and dependency look up?

What is Dependency look up?Could someone please clarify these two concepts.
Since #Michael Zucchetta explained what is the difference in the context of Spring, I'll try to give you a more general explanation. The main difference between the two approaches is "who is responsible for retrieving the dependencies".
Usually, in DI(dependency injection) your component isn't aware of the DI container and dependencies "automagically" appear (e.g. you just declare some setters/ constructor parameters and the DI container fills them for you).
In, DL (dependency lookup) you have to specifically ask for what you need. What this means in practice is that you have a dependency on the context (in spring the Application context) and retrieve whatever you need from it.
You can take a look at ServiceLocator vs DependencyInjection by M. Fowler for a better explanaition, but I'll give you a quote:
The key difference is that with a Service Locator every user of a service has a dependency to the locator. The locator can hide dependencies to other implementations, but you do need to see the locator. So the decision between locator and injector depends on whether that dependency is a problem.
Using dependency injection can help make it easier to see what the component dependencies are. With dependency injector you can just look at the injection mechanism, such as the constructor, and see the dependencies. With the service locator you have to search the source code for calls to the locator. Modern IDEs with a find references feature make this easier, but it's still not as easy as looking at the constructor or setting methods.
Hope this helps.
Dependency lookup is when the object itself is trying to find a dependency, such as:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
MyBean bean = applicationContext.getBean("myBean")
Here, the class itself is initializing the ApplicationContext through an XML, and it is searching in the context for the bean called myBean in the ApplicationContext
The Dependency injection is when a property is automatically bound when an instance is initialized. For example:
in the application-context.xml, we have one line which initialize the bean and another to initialize the object of, let's say, MyClass:
<bean id="myBean" class="org.mypackage.MyBean"/>
<bean id="myClass" class="org.mypackage.MyClass"/>
Then in MyClass, you have something like:
#Component
public class MyClass{
#Autowired
MyBean myBean;
// ...
}
In this case, you have specified that two instances of two beans are initialized. And the myClass bean has a property called myBean which is already initialized due to the injection
Dependency lookup is more traditional approach:
component has to ask for dependency reference from JNDI registry
We can achieve this by the way of two methods:
Dependency Pull
ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/spring/app-context.xml");
SimpleBean mr = ctx.getBean("renderer", SimpleBean.class);
Contextualized Dependency Lookup (lookup is pulled from directly from container, not from registry). Component has to implement specific interface in order to be able execute lookup
public interface Container {
Object dependencyLookup(String key);
}
public class CDL implements Container {
private Dependency dependency;
#Override
public void performLookup(Container container) {
this.dependency = (Dependency) container.dependencyLookup("myDependency");
}
}
Dependency injection is more counterintuitive (but more flexible , scalable):
dependencies are injected into component
There are two ways to do this by:
Constructor
Setter Dependency Injection.

Resources