Java 将 bean 注入 Spring 托管上下文之外的类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/310271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Injecting beans into a class outside the Spring managed context
提问by Spencer Kormos
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. 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.
我是我公司产品之一的最终用户。它不太适合集成到 Spring 中,但是我能够处理上下文并按名称检索所需的 bean。但是,我仍然想知道是否可以将 bean 注入这个类,即使该类不是由 Spring 本身管理的。
Clarification: The same application which is managing the lifecycle of some class MyClass, is also managing the lifecycle of the Spring context. 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.
说明:管理某个类 MyClass 生命周期的同一个应用程序也在管理 Spring 上下文的生命周期。Spring 对 MyClass 的实例一无所知,我想知道如何将实例提供给上下文,但无法在上下文本身中创建实例。
采纳答案by David Tinker
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.
您可以在其中使用@Autowired
等YourClass
来指定要注入的字段等。
回答by Yonatan Maman
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 是 spring 管理的 bean(由 spring 框架构建和管理)x、y 是由您的应用程序构建的非常简单的 POJO,无需 spring 帮助
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 ApplicationContextAwareinterface . 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.
一种方法是实现ApplicationContextAware接口。在这种情况下,我建议 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 -- 约纳坦
回答by Yonatan Maman
Be careful that in oldest version of Spring, there is thread-safe problem with bean factory http://jira.springframework.org/browse/SPR-4672
请注意,在最旧的 Spring 版本中,bean 工厂存在线程安全问题http://jira.springframework.org/browse/SPR-4672
回答by user1204808
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 的一个更好的实现/教程:我希望它可以帮助每个喜欢它的人最终帮助了我。
回答by HDave
Another way to do this is to us use AspectJ. This is the recommended way of injection Spring beans into non-managed objects that are created with the new
operator. See this for details:
另一种方法是让我们使用 AspectJ。这是将 Spring bean 注入使用new
操作符创建的非托管对象的推荐方法。详情请看这个:
http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html
http://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html
回答by Donal Fellows
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
),实际上使背透春实例并把它(它的属性注入和代理那个时候的一代)。
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. (I use this to create instances of an interface where the name of the class to instantiate is defined at runtime.)
您可以将制造所需的属性注入到@Configuration
bean 中。(我使用它来创建接口的实例,其中要实例化的类的名称在运行时定义。)
回答by GreenGiant
If you want to create an object outsidethe Spring context, and make that object available for injection into other beans that arein 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);