Autowire a Spring bean in a Singleton class

PowerLove :

I am trying to autowire a bean inside of a Singleton class, I know that it always a best idea to avoid manual autowiring, but this class is being used in so many places so I do not want to change the caller of this class.

Runner.java

@Component
public class RunnerClass {
    @Autowired
    public ConfigService configService;
}

ConfigService.java

@Service
public class ConfigService {
    private ConfigServiceDAO = ConfigServiceDAO.getInstance();
}

ConfigServiceDAO.java

public class ConfigServiceDAO {

    //Bean I want to autowire here....
    @Autowired
    ConfigServiceDAOBuilder DAOBuilder

    public static ConfigServiceDAO getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        public static final ConfigServiceDAO INSTANCE = new ConfigServiceDAO();

        private SingletonHolder() {}
    }
}

DAOBuilder inside ConfigServiceDAO is always null, which makes sense because my understanding is when the class is instantiated manually, spring injection doesn't happen. What could be the solution here if I want to keep ConfigServiceDAO as non spring component?

====EDIT==== I know it is possible to make ConfigServiceDAO as a spring component and autowire all dependencies. But a lot of classes from different packages already call ConfigServiceDAO.getInstance().someMethod() So I guess the the right question is, what would be the best way to autowire a spring component to the class that is instantiated manually.

Julian :

I don't know your use case but you cannot use @Autowired annotation outside a Spring bean. However if you really need to access a Spring bean from a non Spring piece of code you can do it like below. However this is a very non Spring way of designing your dependencies.

import org.springframework.context.ApplicationContext;

public enum ApplicationContextHolder {
    INSTANCE;

    private ApplicationContext applicationContext;

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

Then you have a configuration class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class SomeConfig {
    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void init() {
        ApplicationContextHolder.INSTANCE.setApplicationContext(applicationContext);
    }
}

Then in your DAO class you get a reference to the builder bean you are interested. Something like this:

public class ConfigServiceDAO {
    public static ConfigServiceDAO getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        public static final ConfigServiceDAO INSTANCE = 
        ApplicationContextHolder.INSTANCE.getApplicationContext().getBean(ConfigServiceDAOBuilder.class).buildConfigServiceDAO()

        private SingletonHolder() {}
    }
}

Again this is a very non Spring way of doing things.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Spring: autowire bean with same type as existing class

Spring Boot autowire field in singleton service/controller by request scoped bean

Spring bean with @Autowire in superclass

Autowire Enum in Spring Bean

Spring Bean and Autowire to datasource

Spring Boot can't autowire map bean in @configuration class

How to autowire a bean in other class in a Spring Boot application?

How to autowire a bean inside a class that is not a configured bean?

Singleton implementation of a Spring bean

Spring singleton bean

Using an autowired singleton bean in a non spring managed java class

Using an autowired singleton bean in a non spring managed java class

When annotating a class with @Component, does this mean it is a Spring Bean and Singleton?

not able to autowire bean in prototype scope in a singleton bean using @Lookup annotation

Is it necessary in a @Configuration class to autowire an @Bean for use in that class?

@Autowire JpaRepository interface class error qualifying bean

Autowire Spring Bean into interface for default method

how to autowire bean in the servlet filters in spring application?

Unable to autowire spring bean in log appender

How do I manually autowire a bean with Spring?

Autowire a bean within Spring's Java configuration

How to Autowire Bean of generic type <T> in Spring?

Spring autowire a stubbed service - duplicate bean

Spring: Autowire bean that does not have qualifier

How to Autowire a OkHttpClient bean in Spring Boot?

Spring autowire only if bean is present as method argument

How to define which bean to autowire in Spring

Not able to autowire a bean using constructor in Spring

Autowire a bean from spring config - Environment specific