Aakash Raj Shakya
Aakash Raj Shakya

Reputation: 33

How to autowire a bean when a new instance of class is created using new keyword

I'm trying to create a new instance of a component using the new keyword. The component class has an auto wiring of another class. In the First class, it has a method which calls the of the second class. The code is as follows:

First.java

@Component
public class First {
    @Autowired
    private Second second;

    public First() {
        System.out.println("This is the first class constructor.");
    }

    public void printFromFirst() {
        second.printFromSecond();
    }
}

Second.java

@Component
public class Second {
    public void printFromSecond() {
        System.out.println("This is inside the second class print method.");
    }
}

Application.java

@SpringBootApplication
public class SampleApplication {

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

    @Bean
    public First first() {
        First first = new First();
        first.printFromFirst();
        return first;
    }
}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'first' defined in com.example.sample.SampleApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.sample.First]: Factory method 'first' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "com.example.sample.Second.printFromSecond()" because "this.second" is null
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.20.jar:5.3.20]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.20.jar:5.3.20]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
    at com.example.sample.SampleApplication.main(SampleApplication.java:11) ~[classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.sample.First]: Factory method 'first' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "com.example.sample.Second.printFromSecond()" because "this.second" is null
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.20.jar:5.3.20]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.20.jar:5.3.20]
    ... 19 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "com.example.sample.Second.printFromSecond()" because "this.second" is null
    at com.example.sample.First.printFromFirst(First.java:16) ~[classes/:na]
    at com.example.sample.SampleApplication.first(SampleApplication.java:17) ~[classes/:na]
    at com.example.sample.SampleApplication$$EnhancerBySpringCGLIB$$badcf278.CGLIB$first$0() ~[classes/:na]
    at com.example.sample.SampleApplication$$EnhancerBySpringCGLIB$$badcf278$$FastClassBySpringCGLIB$$68c83451.invoke() ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.20.jar:5.3.20]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.20.jar:5.3.20]
    at com.example.sample.SampleApplication$$EnhancerBySpringCGLIB$$badcf278.first() ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.20.jar:5.3.20]
    ... 20 common frames omitted

I am able to workout the solution using the dependency injection. I just want to do it this way.

TIA

Upvotes: 0

Views: 1984

Answers (1)

void void
void void

Reputation: 1224

While this is a nasty hack, and I don't think anyone would recommend doing anything like this, this should "work" (it will introduce many problems):

@Component
public class First {

    private static First instance;

    @Autowired
    private Second second;
    
    public First() {
        if (instance != null) {
            this.second = instance.second;
        }
    }

    @PostConstruct
    private void init() {
        instance = this;
    }

}

Upvotes: -1

Related Questions