I have a Data Loader Class which is suppose to load data once the app starts.
My Error -
Could not autowire. No beans of 'OwnerService' Found.
However, my ownerService class is annotated as I have shown below -
This is the class whose supposed to do that -
DataLoader
import model.Owner;
import model.Vet;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import services.OwnerService;
import services.VetService;
import services.map.OwnerServiceMap;
import services.map.VetServiceMap;
#Component
public class DataLoader implements CommandLineRunner {
private final OwnerService ownerService;
private final VetService vetService;
public DataLoader(OwnerService ownerService, VetService vetService) {
this.ownerService = ownerService;
this.vetService = vetService;
}
OwnerServiceMap
package services.map;
import model.Owner;
import org.springframework.stereotype.Service;
import services.OwnerService;
import java.util.Set;
#Service
public class OwnerServiceMap extends AbstractMapService<Owner,Long> implements OwnerService
{//some code here}
The vetService is the same as ownerService.
My applcation class -
package petclinic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class PetclinicApplication {
public static void main(String[] args) {
SpringApplication.run(PetclinicApplication.class, args);
}
}
Maybe I have hierarchy problems, as the application class doesn't search for beans in enough places in the project?
Thank you!
Related
I am trying to connect spring boot application with MySQL for that I have created a interface with name FilterDao which extend JpaRepository class. but whenever I try to make object of implemented class in Service I got this error "Consider defining a bean of type 'com.example.filter.FilterDao' in your configuration" as I am new to spring boot I don't understand this error.
FilterApplication.java
package com.example.filter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}
FilterDao.java
package com.example.filter;
import com.example.filter.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.FluentQuery;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
//#Configuration
public interface FilterDao extends JpaRepository<Filter, Integer> {
}
FilterService.java
package com.example.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class FilterService {
#Autowired
private FilterDao filterDao;
public List<Filter> getData() {
System.out.println("----------------------HERE-------------");
return filterDao.findAll();
}
}
FilterConnector.java
package com.example.filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
public class FilterConnector {
#Autowired
private FilterService filterService;
#GetMapping("/home")
public List<Filter> home()
{
return this.filterService.getData();
}
}
Project Structure
Annotate FilterDao with #Repository
Seems spring has not created bean for FilterDao repository and you are trying to use that`
#Autowired
private FilterDao filterDao;`
There might different reasons for this exception. Please try the below solution.
Use #EnableJpaRepositories(basePackages = "com.example.filter") with your FilterApplication class.
Use #ComponentScan(basePackages = "com.example.*") with FilterApplication class
Use #Repoitory annotation with FilterDao interface.
Hope this helps. For more details check the below tutorial.
https://javatute.com/jpa/consider-defining-a-bean-of-type-in-your-configuration/
It is a very simple program that has a main class as JavaLoader, one interface Student. Student is implemented by two classes.
I have also made a configuration class. When I instantiate the bean from the main class and call a method on Samir. A NoSuchBeanDefinitionException is thrown.
Main class (JavaLoader):
package spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JavaLoader {
public static void main(String[] args) {
AnnotationConfigApplicationContext appContext = new
AnnotationConfigApplicationContext("StudentConfig.class");
Student samir = (Student) appContext.getBean("samir", Student.class);
System.out.println(samir.readsBook());
}
}
StudentConfig class:
package spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan("spring")
public class StudentConfig {
}
Samir class:
package spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
#Component("samir")
public class Samir implements Student{
#Autowired
#Qualifier("history")
Book book;
public Samir(Book book){
this.book = book;
}
public String readsBook(){
return book.readBook();
}
}
The expected output is that the method samir.readsBook() on JavaLoader should be executed
You need to provide a Class instance to the AnnotationConfigApplicationContext constructor:
new AnnotationConfigApplicationContext(StudentConfig.class);
note that StudentConfig.class is not the same as the string "StudentConfig.class".
Note that AnnotationConfigApplicationContext has a string-constructor as well (that's why your code still compiles), but that string is interpreted as a base package for auto-scanning rather than the configuration class name.
Can you please provide me with an example of primitive type dependency injection in spring boot. I have tried once but TestConfiguration which is my custom bean definition class does not detect or does not recognize by spring boot application.
here is my code,
//Engine class
package com.test2.projectTest;
import org.springframework.stereotype.Component;
#Component
public class Engine {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
//Test Configuration
package com.test2.projectTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class TestConfiguration {
#Bean("engine")
public Engine engine(){
Engine engine = new Engine();
engine.setMsg("Message is injected");
return engine;
}
}
//spring main application
package com.test2.projectTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class ProjectTestApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectTestApplication.class, args);
}
}
//JUnit Test
package com.test2.projectTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ProjectTestApplicationTests {
#Test
public void contextLoads() {
ApplicationContext apc = new
AnnotationConfigApplicationContext(TestConfiguration.class);
Engine e = (Engine) apc.getBean("engine");
e.getMsg();
}
}
// Output - org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'engine' available
Please suggest any solution to above issue
Add #componentscan annotation in main class and provide engine class package and it should work
I read a lot about this kind of problem here, but it seems my code is good but the autowire is not working :
Error creating bean with name 'optionController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private service.InteractionBanque controllers.OptionController.interactionBanque; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [service.InteractionBanque] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Here is the code of my Controller :
package controllers;
package controllers;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import serviceimpl.InteractionBanqueImpl;
#Controller
public class OptionController {
#Autowired
private InteractionBanque interactionBanque;
#RequestMapping(value="/virement",method=RequestMethod.GET)
public String index(Model model, #ModelAttribute Client client) {
model.addAttribute("virement", new Virement());
return "virement";
}
#RequestMapping(value="/virement",method=RequestMethod.POST)
public String index(#ModelAttribute Virement virement, Model model) {
return "options";
}
}
And the Code of my Service :
package serviceimpl;
import java.util.HashMap;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import dao.BanqueDAO;
import daoimpl.BanqueDaoImpl;
import model.Banque;
import model.Client;
import service.InteractionBanque;
import utils.SendRequest;
#Service
public class InteractionBanqueImpl implements InteractionBanque {
public static final int END_ID_BANQUE = 5;
public static final String LOGIN_URL = "/account";
public boolean connecter(Client client) {
some code
}
}
And The code of the interface :
package service;
public interface InteractionBanque {
boolean connecter(Client client);
}
And my Application class define the #SpringBootApplication which should be use to wire everything :
package controllers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
SO I don't get it, for me this should do the work but the autowired is not working.
Help would be appreciated :)
#SpringBootApplication scans only package (recursively) within a class that uses it. InteractionBanqueImpl is in another package.
Create a package 'app' with Application class, and then move to it controllers and and other packages. Should be fine.
As #Mati said, you have a problem with packages.
Create a root package for your application and move everything under it, so you have it something like this:
+ myapp
Application.java
+ controller
+ service
+ serviceimpl
The answers you have about putting your Application class in a parent package of the rest of your code will work, but an alternative, if you don't want to change your package structure, would be to use the #ComponentScan annotation, specifying the packages that contain components you want to autowire, for example:
#ComponentScan(basePackages = {"serviceimpl", ...}
I try to use Springs own Dependency Injection in a Junit test case:
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.binarisinformatik.api.AppConfig;
import org.binarisinformatik.satzrechner.SatzRechner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=AppConfig.class)
//#SpringApplicationConfiguration(classes = {AppConfig.class})
public class SatzRechnerTest {
#Autowired
private SatzRechner satzRechner; //SUT
#Before
public void setUp() {
// AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SatzRechnerTest.class);
//satzRechner=context.getBean(SatzRechner.class);
}
#Test
public void addiere_satz_4komma6_zu_zahlwert_10() {
assertThat("Addition von \"4,6\" ergibt nicht 10!",
satzRechner.summe("4,6"), is(equalTo(10)));
}
Im testing a class names SatzRechner in which Spring should also autowire some variables. Here is my Class under test:
#Component
public class SatzRechner {
#Autowired //#Inject
private Rechner taschenRechner;
#Autowired
private Zahlenfabrik zahlenfabrik;
public Integer summe(String zeichenSatz) {
return taschenRechner.summe(zahlenfabrik.erzeugeZahlen(zeichenSatz));
}
}
And AppConfig.class which is using as Configurationfile looks like that:
#Configuration
#ComponentScan(value={"org.binarisinformatik"})
public class AppConfig {
}
What is here the problem?
If you want to use a Spring configuration class, this one must have beans definitions. Please find an example below :
Test class:
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.binarisinformatik.api.AppConfig;
import org.binarisinformatik.satzrechner.SatzRechner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=AppConfig.class)
public class SatzRechnerTest {
#Autowired
private SatzRechner satzRechner;
#Test
public void addiere_satz_4komma6_zu_zahlwert_10() {
assertThat("Addition von \"4,6\" ergibt nicht 10!",
satzRechner.summe("4,6"), is(equalTo(10)));
}
}
Configuration class :
You have to declare #Bean annotated methods. These beans are managed by Spring container.
#Configuration
public class AppConfig {
// Beans present here will be injected into the SatzRechnerTest class.
#Bean
public SatzRechner satzRechner() {
return new SatzRechner();
}
#Bean
public Rechner taschenRechner() {
return new TaschenRechner();
}
#Bean
public Zahlenfabrik zahlenfabrik() {
return new Zahlenfabrik();
}
}
Note : I let you properly handle returned types here and beans parameters (if present in your context).
There are two things you have to ensure before you run the test case successfully:
1) Classes SatzRechner, Rechner & Zahlenfabrik should be under "org.binarisinformatik" package
2) Classes Rechner & Zahlenfabrik should also be annotated with #Component as SatzRechner.