简体   繁体   English

将bean注入Spring托管上下文之外的类中

[英]Injecting beans into a class outside the Spring managed context

I'm an end-user of one of my company's products. 我是我公司产品的最终用户。 It is not very suitable for integration into Spring, however I am able to get a handle on the context and retrieve the required bean by name. 它不太适合集成到Spring中,但是我能够处理上下文并按名称检索所需的bean。 However, I would still like to know if it was possible to inject a bean into this class, even though the class is not managed by Spring itself. 但是,我仍然想知道是否有可能将bean注入到这个类中,即使该类不是由Spring本身管理的。

Clarification: The same application which is managing the lifecycle of some class MyClass, is also managing the lifecycle of the Spring context. 澄清:管理某些类MyClass生命周期的同一个应用程序也在管理Spring上下文的生命周期。 Spring does not have any knowledge of the instance of MyClass, and I would like to some how provide the instance to the context, but cannot create the instance in the context itself. Spring对MyClass的实例没有任何了解,我想知道如何将实例提供给上下文,但不能在上下文本身中创建实例。

You can do this: 你可以这样做:

ApplicationContext ctx = ...
YourClass someBeanNotCreatedBySpring = ...
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(
    someBeanNotCreatedBySpring,
    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, true);

You can use @Autowired and so on within YourClass to specify fields to be injected etc. 您可以在YourClass使用@Autowired等来指定要注入的字段等。

One way to bring a bean into Spring despite its manufacture being external is to use a helper class marked as a @Configuration bean that has a method (marked with @Bean ) that actually makes the instance and hands it back through Spring (which does its property injection and proxy generation at that point). 将bean引入Spring的一种方法是使用标记为@Configuration bean的辅助类,该类具有一个方法(用@Bean标记),该方法实际生成实例并通过Spring将其传回(Spring此时的属性注入和代理生成)。

I'm not quite sure what scope you need; 我不太清楚你需要什么范围; with prototype , you'll get a fresh bean in each place. 有了prototype ,你会在每个地方都得到一个新鲜的豆子。

@Configuration
public class FooBarMaker {
    @Bean(autowire = Autowire.BY_TYPE)
    @Scope("prototype")
    public FooBar makeAFooBar() {
        // You probably need to do some more work in here, I imagine
        return new FooBar();
    }
}

You can inject properties required for manufacture into the @Configuration bean. 您可以将生产所需的属性注入@Configuration bean。 (I use this to create instances of an interface where the name of the class to instantiate is defined at runtime.) (我用它来创建一个接口实例,其中要实例化的类的名称是在运行时定义的。)

suppose that u have the following dependency chain: 假设你有以下依赖链:

A --> B --> C --> x --> y -- > Z A - > B - > C - > x - > y - > Z.

A, B, C are spring managed beans (constructed and manged by spring framework) x, y are really simple POJOs that constructed by your application, without spring assistance A,B,C是弹簧管理的bean(由弹簧框架构造和管理)x,y是由您的应用程序构建的非常简单的POJO,没有弹簧辅助

now if you want that y will get a reference to Z using spring that you need to have a 'handle' to the spring ApplicationContext 现在如果你想要y将使用spring获得对Z的引用,你需要对spring ApplicationContext有一个'句柄'

one way to do it is to implement ApplicationContextAware interface . 一种方法是实现ApplicationContextAware接口。 In this case I would suggest that either A, B or C will implement this interface and will store the applicationContext reference in a static member. 在这种情况下,我建议A,B或C将实现此接口,并将applicationContext引用存储在静态成员中。

so lets take Class C for example: 所以我们以C类为例:

class C implmenets ApplicationContextAware{
    public static ApplicationContex ac;
     void setApplicationContext(ApplicationContext applicationContext)  {
               ac = applicationContext;
     }
 .............
}

now, in class y you should have: 现在,在y级你应该:

(Z)(C.ac.getBean("classZ")).doSomething()

HTH -- Yonatan HTH - Yonatan

Another way to do this is to us use AspectJ. 另一种方法是使用AspectJ。 This is the recommended way of injection Spring beans into non-managed objects that are created with the new operator. 这是将Spring bean注入使用new运算符创建的非托管对象的推荐方法。 See this for details: 有关详细信息,请参见

http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html

Searching endless combos of autowire inject spring bean into pojo applicationcontextaware beanaware etc circled me back here but this didnt provide a complete enough solution for me. 搜索无限组合的autowire注入spring bean到pojo applicationcontextaware beanaware等圈回我这里,但这并没有为我提供一个完整的解决方案。

This is a much better implementation/tutorial of this IMO: I hope it helps everyone like it finally helped me. 这是一个更好的IMO实现/教程:我希望它能帮助每个喜欢它的人最终帮助我。

Accessing Spring Beans from outside Spring Context 从Spring Context外部访问Spring Bean

If you want to create an object outside the Spring context, and make that object available for injection into other beans that are in the Spring context, you can follow the steps in this article . 如果要在Spring上下文之外创建一个对象,并使该对象可用于注入Spring上下文中的其他bean, 可以按照本文中的步骤操作。

Basically, you create a parent application context and push your external object into this parent context as a singleton. 基本上,您创建父应用程序上下文并将外部对象作为单例推送到此父上下文中。 Then you create you main application context (for example, from xml files), with the parent application context as its parent. 然后,您将创建主应用程序上下文(例如,从xml文件),并将父应用程序上下文作为其父项。

Object externalObject = ...
GenericApplicationContext parent = new StaticApplicationContext();
parent.getBeanFactory().registerSingleton( "externalObject", externalObject );
parent.refresh();
ApplicationContext appContext = new ClassPathXmlApplicationContext( ... , parent);

请注意,在最古老的Spring版本中,bean工厂存在线程安全问题http://jira.springframework.org/browse/SPR-4672

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM