-1

I have my non-spring public class MySingleton which has a MyBattis Mapper injected via Spring as follows:

public class MySingleton{

    @Autowired
    MyMapper myMapper

    private List<MyPojo> myList;
    private MySingleton(){
       myList = myMapper.getMyList();
    }

    public static MySingleton getInstance(){        
        if(instance == null){//first check
            synchronized (MySingleton.class) {
                if(instance == null){// second check
                    instance = new MySingleton();                   
                }       
            }           
        }
        return instance;
    }
}

myMapper is never initialized, it's always null on the constructor. I have tested that the bean is declared and created before my Singleton, I have tried Configurable annotation too and nothing works.

Can anyone help me?

Pablo Mosby
  • 309
  • 1
  • 2
  • 14
  • [Autowiring bean properties is called after the bean's constructor is called](https://stackoverflow.com/a/6336013/833070), plus you're class isn't annotated as a bean. Either annotate your constructor with `@Autowired` and add the `MyMapper` as a parameter to your constructor or call `myMapper.getMyList();` in another method than your constructor. – Draken Oct 24 '19 at 16:50
  • 2
    Possible duplicate of [@Autowired bean is null when referenced in the constructor of another bean](https://stackoverflow.com/questions/6335975/autowired-bean-is-null-when-referenced-in-the-constructor-of-another-bean) – Draken Oct 24 '19 at 16:53
  • 1
    @Draken The class `MySingleton` is not mapped as a spring bean. I think this is not a duplicated question. – Cristiano Bombazar Oct 24 '19 at 18:46

4 Answers4

1

To retrieve a managed spring bean on a non-managed class, I wrote a class that does what are you trying to do.

@Configuration
public class ApplicationContextProvider {

    private static ApplicationContext context;

    public ApplicationContextProvider(ApplicationContext context){
        ApplicationContextProvider.context = context;
    }

    public static ApplicationContext getContext() {
        if (Objects.isNull(ApplicationContextProvider.context)) {
            throw new IllegalStateException("Context isn't available!");
        }
        return ApplicationContextProvider.context;
    }

    public static <E> E getBean(Class<E> bean){
        return getContext().getBean(bean);
    }
}

To get a managed bean, just to ApplicationContextProvider.getBean(MyMapper.class);

Cristiano Bombazar
  • 984
  • 2
  • 7
  • 15
0

You can implement the ApplicationContextAware interface in non managed classes. This will result in the application context being injected through a setter, and allows you to access the rest of the Spring ecosystem.

Then you can just call applicationContext.getBean(MyMapper.class);.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
-1

Annotate MyMapper class @Component annotation.It means that Spring framework will autodetect these class for dependency injection when annotation-based configuration and classpath scanning is used.

avishka eranga
  • 105
  • 1
  • 11
-1

MyMapper this class is not register as a bean in IOC. First register MyMapper class with @Component or XML file as bean then run