【问题标题】:Spring use @Autowired field not in @Component [duplicate]Spring使用@Autowired字段不在@Component中[重复]
【发布时间】:2016-11-14 12:25:14
【问题描述】:

我的应用中有一个案例,我需要使用对象AccountsDao accountsDao

public class Account {

    @Autowired
    private AccountsDao accountsDao;

没有将属性@Component 放到Account 类中(并且没有任何其他方法将其标记为spring bean)。

应用程序很大,有一个客观原因为什么Account不能是Spring Bean,必须手动初始化。

我也知道这是单例,通用结构还可以。

有没有办法做到这一点?

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    添加 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;
        }
    
    }
    

    使用

    AccountsDao accountsDao = SpringUtils.getBean(AccountsDao.class);
    

    【讨论】:

    • 感谢这是我所见过的最好的选择
    • 这会破坏您在使用 Spring 时所采用的控制反转模式。 Account 现在将自行收集它的依赖项,而不是从外部获取它们。这样的代码更难测试,因为您现在需要记住在测试中使用Account 时正确设置SpringUtils
    【解决方案2】:

    您不应该这样做,尤其是没有 BeanUtils(绝对反模式)并且有原因,为什么默认情况下不支持。如果您真的需要 DAO,请执行类似的操作

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

    编辑:这是你的称呼:

    @Component
    public class MyBusinessLogicClass {
      @Autowired
      private AccountDao accountDao;
    
      public void doMyBusinessLogic(Account account) {
        account.doSomethingWithDao(accountDao);
      }
    }
    

    【讨论】:

    • 我没听懂你。从那时起它在哪里得到AccountDao accountDao
    • 你只有在你需要的方法中有accountDao。这取决于您需要 accountDao 的用途,但 Account 的外部调用者将注入 accountDao 并将其作为参数提供给 Account,仅用于方法的上下文。
    【解决方案3】:

    您可以通过编程方式获取 spring 上下文并从中获取 AccountsDoa。您可以在 Account 构造函数中执行此操作。 Spring get current ApplicationContext 第二个响应。

    【讨论】:

      【解决方案4】:

      如果AccountsDaoAccount 的构造时可用,您可以自己进行构造函数注入。

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

      除此之外还有@Configurable,但据我所知,这需要AspectJ。

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

      Spring autowiring using @Configurable

      【讨论】:

      • 那不是可选的,不可用。
      猜你喜欢
      • 2015-09-14
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 2015-01-21
      相关资源
      最近更新 更多