如何从运行时创建的非bean对象自动装配spring bean?

时间:2016-01-04 08:57:55

标签: spring autowired configurable

我有一些Jpa存储库和几个Entity类。我需要为我的一个实体创建一个辅助对象。在帮助者里面,我使用@Autowire来访问Jpa存储库。

@Entity
class A {
    @Transient
    Helper helper;

    ...

}

class Helper {
    A a;
    @Autowired
    CRepository repo;

    public Helper(A a) {
        this.a = a;
    }
}

但是,repo始终为null。我已经尝试过使用SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)和@Configurable,但两者都失败了。有人可以为我提供一些提示吗?

BTW,A在休息控制器中实例化。

谢谢!

4 个答案:

答案 0 :(得分:2)

您可以使用BeanUtil类来获取在Springl中创建的任何bean

@Service
public class BeanUtil implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }
}

那你就可以得到豆子了。

MyBean obj = BeanUtil.getBean(MyBean.class);

答案 1 :(得分:0)

使用构造函数注入而不是字段注入;无论如何,这是最好的做法。然后将A注入控制器并将其作为构造函数参数传递是微不足道的。

答案 2 :(得分:0)

@Configurable注释工作正常,但您需要在任何配置类中使用@EnableSpringConfigured注释才能使其工作。在其他stackoverflow帖子中阅读我的答案:spring autowiring not working from a non-spring managed class

实体类不应包含任何帮助程序,即使是瞬态的。对于简洁的设计,您需要分离关注点,因此实体不应该了解您的业务逻辑。我不能帮助你,因为我不知道那个助手的目标是什么,但是你还有其他选择:

ALTERNATIVE 1(基于你的描述,似乎帮助器是一个有状态的bean,所以它不是候选者成为@Service,我个人认为它应该是)

mainsite.com/example.html

ALTERNATIVE 2(让你的Helper类无状态,以便spring知道你的bean而不需要像@ Confgurable / @ EnableSpringConfigured这样的额外内容)

@Controller
public MyController {
    @RequestMapping(...)
    public void processRequest() {
        A a = new A();
        ...
        Helper helper = new Helper(a);  // CRepository is successfully autowired
    }
}

@Configurable(autowire = Autowire.BY_TYPE)
public class Helper {
    A a;
    @Autowired
    CRepository repo;
}

@Configuration
@EnableSpringConfigured
public Application {
    ...
}

答案 3 :(得分:-1)

您无法在Helper类中自动装配任何内容,因为它不受Spring管理。 您可以使用此方法:

public class HelperManager {
  @Autowired
  private ApplicationContext context;

  public Helper getHelper(A a) {
    return context.getBean(Helper.class, a);
}

将Helper配置为原型bean:

@Configuration
public class MyConfiguration {
  @Bean
  public HelperManager helperManager() {
    return new HelperManager();
  }

  @Bean
  @Scope("prototype")
  public Helper helper(A a) {
    return new Helper(a);
  }
}

最后在你的控制器中:

@Controller
public class MyController {
  @Autowired
  private HelperManager helperManager;

  public someMethodWhereToInstanceYourHelper(A a) {
    ...
    Helper helper = helperManager.getHelper(a);
    ...
  }
}