0

Suppose I have

@Service 
public class myService () {
    public void sayHello() {
        System.out.println("Hello");
    }

}

public class myTestClass() {
    @Autowired
    private myService thisService;

    public void transferHello() {
        thisService.sayHello(); 
    }

}

public class Application() {
    public static void main(String[] args) {
        SpringApplication.run(PilContainerApplication.class, args);
        myTestClass thisTest = new myTestClass();
        thisTest.transferHello();
    }
}

Since myTestClass() is not a bean like service/controller, thisService would have a null reference when I use myTestClass thisTest = new myTestClass();.

I was wondering how to overcome this.. I tried using public static myService thisService and it said cannot use @Autowired on static fields.

Thank you

FranktheTank
  • 292
  • 3
  • 9
  • 2
    `myTestClass` has to be marked with spring stereotype too. – Michał Krzywański Jul 30 '19 at 19:16
  • 2
    Take care of java naming conventions. Class names should start with upper case character. – Jens Jul 30 '19 at 19:16
  • 2
    Why you do not make testclass to a bean? – Jens Jul 30 '19 at 19:17
  • 1
    Why can't you make `myTestClass` a spring bean? – clav Jul 30 '19 at 19:18
  • 1
    And also you are creating the object of class yourself through `new` operator. – Michał Krzywański Jul 30 '19 at 19:18
  • @ michalk yeah, thats the problem. I don't want myTestClass to have a spring stereotype. I just want to get the bean of myService. Am I supposed to just have spring annotations over all my classes in current Java Spring development? I am new to java spring – FranktheTank Jul 30 '19 at 19:19
  • 1
    So Spring will not be able to help you to inject with field injection. Consider using constructor injection and passing dependency manually through constructor. – Michał Krzywański Jul 30 '19 at 19:20
  • 2
    @FranktheTank If you want to autowire, you need to declare your class as bean. Otherwise, you can [retrieve a bean programmatically](https://stackoverflow.com/questions/25775888/retrieve-bean-programmatically) (although this requires the `ApplicationContext`...) – Turing85 Jul 30 '19 at 19:20
  • How about making it a bean using @Component ? – Ajay V Jul 30 '19 at 19:55

2 Answers2

2

if you want inject bean B without marking bean A via some annotation, or xml definition, you can use SpringBeanAutowiringSupport

public class A {

    @Autowired
    private class B b;

    public A{
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 
    }

}
2

When a class cannot be changed to be annotated with a Spring stereotype, @Bean is a very good alternative :

@Configuration
public class MyBeansConfiguration {

   @Bean
   public MyTestClass getMyTestClass(MyService myService) {
       return new MyTestClass(myService);
   }
}

You can inject it now in your Application class :

public class PilContainerApplication {

    @Autowired
    MyTestClass myTestClass;


    @PostConstruct
    public void init(){
        myTestClass.transferHello();            
    }

    public static void main(String[] args) {
        SpringApplication.run(PilContainerApplication.class, args);
    }    
}

Note that beans are instances of class and are injected in other instances of class that depend on them. So you don't have access to the injected beans in the static main() method. But you have access to it in an instance method annotated with @PostConstruct that will be executed when the dependencies were injected in the current bean.
Side note : classes have to start with an uppercase. I did it in the provided code.

davidxxx
  • 125,838
  • 23
  • 214
  • 215