azimut3
azimut3

Reputation: 17

Spring application context has my bean but @autowired doesn't see it

I am trying to configure my Spring Boot application with annotations and to use @Autowired annotation in it. When I check whether I have my Bean loaded or not, it is loaded, but with @Autowired it says NoSuchBeanDefinitionException

As you can see further I tried to check if my Beans were actually loaded, so when I run my application, I can see my Bean's name in the console. Also, I tried to add 'scanBasePackages = "com.log.iei.Logistica"' to my @SpringBootApplication annotation, but it changed nothing. Also, I tried field autowiring

Here is my main class:

@SpringBootApplication(scanBasePackages = "com.log.iei.Logistica")
public class LogisticaApplication extends Application {
   public static ConfigurableApplicationContext context;

   @Override
   public void init() throws Exception {
       SpringApplicationBuilder builder = new SpringApplicationBuilder(AppConfig.class);
       context = builder.run(getParameters().getRaw().toArray(new String[0]));
       String[] beanNames = context.getBeanDefinitionNames();
       Arrays.sort(beanNames);
       for (String beanName : beanNames) {
           System.out.println(beanName);
       }

   }

Here is part of VehicleService class:

@Component("vehicleService")
public class VehicleService implements IDao<VehicleEntity> {

    private static VehicleService vehicleService;
    GenericDao<VehicleEntity> dao;

    public VehicleService(){
        dao = new GenericDao<>(VehicleEntity.class);
        System.out.println("==== VehicleService was created ====");
    }

Here is part of @Autowired part:

@Component("cargoPage")
public class CargoPage extends TablePageTemplate {

    @Autowired
    public CargoPage(VehicleService vehicleService){
        getAboveTableLine().getChildren().addAll(getAboveTableLineSetup());

        setTable(getTable(), vehicleService.findAll(), VehicleEntity.getTableMapping());

And here is an error:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.log.iei.Logistica.data.controllers.Services.VehicleService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
    ... 24 more

UPD: Maybe the problem is with VehicleService implementing Generic interface.

Upvotes: 0

Views: 2028

Answers (2)

Ilya Sereb
Ilya Sereb

Reputation: 2561

First, you have to set your base package to this:

@SpringBootApplication(scanBasePackages = "com.log")

You mapped everything correctly, however, the constructor used to @Autowire beans is not supposed to invoke any other logic. If you need to do something right after bean initialization use @PostConstruct.

This is how your code would look like:

@Service
public class CargoPage extends TablePageTemplate {

    private VehicleService vehicleService;

    @Autowired
    public CargoPage(VehicleService vehicleService) {
        this.vehicleService = vehicleService;
    }

    @PostConstruct
    public void init() {
        getAboveTableLine().getChildren().addAll(getAboveTableLineSetup());
        setTable(getTable(), vehicleService.findAll(), VehicleEntity.getTableMapping());
    }
}

Upvotes: 1

Ricardo
Ricardo

Reputation: 11

You should check if your files are inside base packages. For example, if you have:

com.log
       .service
               VehicleService.java
               CargoPage.java
       LogisticaAplication.java

So, inside your LogisticaApplication.java, you should add the base as the following:

@SpringBootApplication(scanBasePackages = "com.log")
public class LogisticaApplication extends Application {
   public static ConfigurableApplicationContext context;

   @Override
   public void init() throws Exception {
       SpringApplicationBuilder builder = new SpringApplicationBuilder(AppConfig.class);
       context = builder.run(getParameters().getRaw().toArray(new String[0]));
       String[] beanNames = context.getBeanDefinitionNames();
       Arrays.sort(beanNames);
       for (String beanName : beanNames) {
           System.out.println(beanName);
       }

   }

Upvotes: 1

Related Questions