#Spring @Autowired abstract vs interface

1 messages · Page 1 of 1 (latest)

hollow tartan
#

First time using Java, and first time using Spring I have an issue with the DI, I tried this and this is works:

public interface MyInterface {
    void someMethod();
}

@Component
public class A implements MyInterface {
    public void someMethod() { }
}

@Component
public class B implements MyInterface {
    public void someMethod() { }
}

@Component
public class MyMain {
    public MyMain(@Autowired LinkedList<MyInterface> y) { }
}```

I can run over y and I will have A & B

But for some reason when I try to do this:

public interface MyInterface {
void someMethod();
}

public abstract class MyAbstractClass implements MyInterface { }

@Component
public class A extends MyAbstractClass {
@Override
public void someMethod() { }
}

@Component
public class B extends MyAbstractClass {
@Override
public void someMethod() { }
}

@Component
public class MyMain {
public MyMain(@Autowired LinkedList<MyInterface> y) { }
}```

y is empty, I tried to debug and it seems it first creates MyMain in the second, in the first example it MyMain is created after all of MyInterface implementations.

How can I fix this so the second example will work?

proper heartBOT
#

<@&987246841693360200> please have a look, thanks.

proper heartBOT
#

While you are waiting for getting help, here are some tips to improve your experience:

Code is much easier to read if posted with syntax highlighting and proper formatting.

If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.

Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.

#

Here is an AI assisted attempt to answer your question 🤖. Maybe it helps! In any case, a human is on the way 👍. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#

method();
}

@Component
public class MyImplementation implements MyInterface {
public void someMethod() {
// implementation code
}
}

@Service
public class MyService {
@Autowired
private MyInterface myInterface;

public void doSomething() {
    myInterface.someMethod();
}

}

But when I change `MyInterface` to an abstract class, it doesn't work anymore:

public abstract class MyAbstractClass {
public abstract void someMethod();
}

@Component
public class MyImplementation extends MyAbstractClass {
public void someMethod() {
// implementation code
}
}

@Service
public class MyService {
@Autowired
private MyAbstractClass myAbstractClass;

public void doSomething() {
    myAbstractClass.someMethod();
}

}

I get the following error:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.MyAbstractClass' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Why does it work with an interface but not with an abstract class?
hollow tartan
#

I tried to add "Component" to the abstract and it didn't helped, also tried to let the classes that extends the abstract also to implement the interface, didn't help

hollow tartan
#

When I added in my MyMain constructor parameter type A it did created the object before MyMain and I have access to it, but y was still empty, also removed the abstract from the classes A & B and just implemented the interface but for some reason that didn't work.

elfin compass
#

@hollow tartan Quick solution would be to change your linkedlist to a List<MyInterface>

#

It supports collections, but it has no idea what an ArrayList<MyInterface> or a LinkedList<MyInterface> is

#

if you want it to support this

#
@Configuration
public class Config {
    private final ApplicationContext applicationContext;
    
    public Config(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Bean
    LinkedList<MyInterface> getStuff() {
        Map<String, MyInterface> beans = applicationContext.getBeansOfType(MyInterface.class);
        return new LinkedList<>(beans.values());
    }
}
#

Also note you do not need to provide @Autowired