Spring get bean without implementation - spring

I try do all things as here
https://spring.io/guides/gs/accessing-data-jpa/
But i get error, when try repeat this line
ConfigurableApplicationContext context = SpringApplication.run(Application.class);
in my app this seems so
#Autowired
private ConfigurableApplicationContext appContext;
error that i get when call getBean function
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [ru.tcsbank.target.core.service.TestRepository] is defined: expected single bean but found 0:
What is the problem with this example?

There are a number of issues that could be causing this. Code from the TestRepository object would be helpful.
From what you've provided, my best guess is that some object, likely the TestRepository, is being wired in, but is missing the annotation to tell Spring it's a bean. Check that the proper objects have #Entity, #Service, #Component, and #Repository.

You have to add a #Repository annotation to your TestRepository.

Related

#MockBean injected into a constructor-autowired component

From the official documentation:
When registered by type, any existing single bean of a matching type (including subclasses) in the context will be replaced by the mock
What if the service under test is autowired in the constructor, though? E.g. in Kotlin (I suppose #MockkBean and #MockBean work the same regarding DI):
#RunWith(SpringRunner.class)
class ExampleTests #Autowired constructor(val userOfService: UserOfService) {
#MockkBean
private lateinit var service: ExampleService
...
}
I would expect this example to fail because in order to instantiate ExampleTests Spring has to first obtain a proper instance of UserOfService. That shouldn't be possible at that time, though, because there's no bean of type ExampleService in the application context yet.
Contrary to my expectation, this works. How is it possible?
Because you miss the other part from the documentation :
In either case, if no existing bean is defined a new one will be
added.
So #MockBean will also instantiate a bean automatically if that bean is not found in the spring context.
The sequence of actions are mainly as follows :
Start up the spring context which create all the spring BeanDefinition only that are registered in the spring context.
Process #MockBean which will replace the BeanDefinition in (1) or create a new BeanDefinition
Actually instantiate all the beans based on these BeanDefinition. It will handle which bean to be actually instantiated first and later.
Create a test instance (i.e ExampleTests) to execute its test methods. If any beans required to be auto-wired into the test instance are not created , it will fail.
So as long as you define UserOfService bean , ExampleTests can be instantiated as you are now using #MockBean on the ExampleService which means it must exist no matter you define it or not in the spring context for the test.

Spring Bean and Autowire to datasource

Noob to Spring. I have 2 files:
foo-servlet.xml which has the following statement:
<bean id:"DAO" class="a.b.data.MyDAO"/>
fooController.java has the following:
#Controller
public class FooController{
#Autowired
private FooDAO fooDAO;
public void setFooDAO (FooDAO fooDAO){ this.fooDAO = fooDAO;}
My question: Is Spring actually replacing / injecting the definition of DAO in the servlet into my FooDAO? I'm trying to understand the 'tie-in' between the bean and how Spring know to substitute that file for my FooDAO in the controller.
Oh, and there is no mention of #Repository or #Component anywhere in this example code...
The XML looks kind of corrupted. I think it needs to be id=DAO
As far as i know: Autowiring is either done via the type or the name and the type.
So when MyDAO implements FooDao your bean will be considered for Autowiring.
But this is just a guess. The code of the Daos and the rest of the configuration would be helpful to give a correct answer to this question.
Understanding Spring #Autowired usage
This might answer your question as well.

How do I autowire an instance of a java class?

I have a class that starts like this:
import javax.mail.Session;
//... more imports
#Component("eMailUtility")
public class MailUtility {
#Autowired
Session mailSession;
//...
}
My IDE tells me "Could not autowire. No beans of 'Session' type found."
This message doesn't surprise me, but I'm not sure how to fix it. Session is a final class with factory methods but no public constructors. I can easily instantiate a Session somewhere, but I don't know what I need to do to make it recognizable as a target of an autowired injection. All the examples I've found on the internet show how to autowire an instance of a class that I wrote, which doesn't help me here.
(A detailed explanation of exactly how autowire works, which doesn't gloss over anything, would be very helpful, but I can't seem to find one. If you know of a good link, that would be helpful.)
You'd have to create a method in a class that is annotated with #Configuration that returns a Session object and annotate that method with #Bean. In your case something like this:
#Bean
public Session session() {
return <instance>;
}
If it was one of your own classes you could also annotate it with #Component, or other annotations that are itself annotated with #Component. Spring would then find the class with this annotation and automatically create the bean for you.
For an explanation about #Autowired you can look at this answer: Understanding Spring #Autowired usage

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.

spring autowired aop circular dependency

I'm using java config with #ComponentScanin order to initialize my beans
and #EnableAspectJAutoProxy(proxyTargetClass=true)to use cglib proxies.
In this project we have a lots of generated services autowired between them using #Autowired. It works pretty well.
But, for some of these services I've added #Async (I've also added #EnableAsync(proxyTargetClass = true)on my #Configurationclass).
After that, I'm getting:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'ConversationUserLocalService': Bean with name 'ConversationUserLocalService' has been injected into other beans [ConversationUserHistoryLocalService] i
n its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'a
llowEagerInit' flag turned off, for example.
I guess this is because Spring is injecting the service with #Asyncmethod BEFORE AOP creates the proxy.
Could this be the problem?
How I should fix it?
In order to try to clarify my problem, let's say I have:
#Service A, B & C;
A has autowired B & C, B has autowired A & C, C has autowired A & B;
C has a method marked as #Async.
When Spring initialize applicationContext, it tries to initialize A, but needs B & C, so it initializes them. But after all, AOP tries to make a proxy of C (because #Async) and then it detects that autowired C into B and A is not the same as proxy of C so it fails.
I hope this can explain a little more what is happening.
Finally I sorted it out using #Lazyon services (with methods annotated with #Async), and also, where they were autowired.
This way I guess Spring only initialize and autowires those services when they're required instead of on application context initialization.
I have same issue and I solved this issue:
I identified which #Autowired property is reason for circular dependency.
Eg:
#Autowired
private TestService testService;
(Tips to identified just try to comment and find out which property is reason to break the application)
Once identified just use #Lazy on top of this #Autowired variable.
Eg :
#Lazy
#Autowired
private TestService testService;
And Application worked smoothly.
AsyncConfigurer configuration classes get initialized early in the application context bootstrap. If you need any dependencies on other beans there, make sure to declare them #Lazy as far as possible in order to let them go through other post-processors as well.
Reference JavaDoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html
I managed to fix a similar issue by adding #Qualifier together with #Autowire, for example:
#Autowired
#Qualifier("publisher")
private Publisher publisher;

Resources