0

I Have a case in my app, that i need to use the object AccountsDao accountsDao

public class Account {

    @Autowired
    private AccountsDao accountsDao;

without putting an attribute @Component to Account class(and without any other method to mark it as a spring bean).

The app is huge, and there is an objective reason why Account must not be a Spring Bean and must be initialized manually.

I also know that this is a single case, and the common structure is OK.

Is there a way to do that?

user1935987
  • 3,136
  • 9
  • 56
  • 108

4 Answers4

5

add SpringUtils.java

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

@Component
public class SpringUtils implements BeanFactoryPostProcessor {

    private static ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
        // TODO Auto-generated method stub
        SpringUtils.beanFactory = arg0;
    }

    public static <T> T getBean(Class<T> clz) throws BeansException {
        T result = (T) beanFactory.getBean(clz);
        return result;
    }

}

use

AccountsDao accountsDao = SpringUtils.getBean(AccountsDao.class);
denghb
  • 89
  • 2
  • thanks this is the best option from what i've seen – user1935987 Jul 12 '16 at 10:38
  • 1
    This destroys the Inversion of Control pattern that you go for when using Spring though. The `Account` will now gather it's dependencies by itself instead of getting them from the outside. Code like this is harder to test, as you now need to remember to set up the `SpringUtils` correctly when the `Account` is used in tests. – FrontierPsychiatrist Jul 12 '16 at 11:07
1

You should not do this, especially no BeanUtils (absolute anti pattern) and there are reasons, why this is not supported by default. If you really need the DAO, do something like

public class Account {
  public void doSomethingWithDao(AccountDao accountDao) {
    // TODO do somthing with dao, but do not store it in a field
  }
} 

Edit: Here is it how you would call it:

@Component
public class MyBusinessLogicClass {
  @Autowired
  private AccountDao accountDao;

  public void doMyBusinessLogic(Account account) {
    account.doSomethingWithDao(accountDao);
  }
}
  • i didn't get you. where it gets `AccountDao accountDao` from then? – user1935987 Jul 12 '16 at 10:51
  • You only have the accountDao in the method where you need it. It depends on what you need the accountDao for, but the outer caller of Account will have the accountDao inject and give it to Account as parameter only for the context of the method. – Sebastian Waschnick Jul 12 '16 at 19:25
0

You can get spring context programmaticaly and get AccountsDoa from it. You can do that in Account constructor. Spring get current ApplicationContext The second response.

Community
  • 1
  • 1
Mr_Thorynque
  • 1,749
  • 1
  • 20
  • 31
0

You can just do constructor injection yourself if you have the AccountsDao available at construction time of the Account.

public class Account {

    private final AccountsDao accountsDao;

    public Account(AccountsDao accountsDao) {
        this.accountsDa = accountsDao;
    }
}

Apart from that there is @Configurable, but that requires AspectJ as far as I know.

http://olivergierke.de/2009/05/using-springs-configurable-in-three-easy-steps/

Spring autowiring using @Configurable

Community
  • 1
  • 1
FrontierPsychiatrist
  • 1,343
  • 10
  • 20