Java 如何将依赖项注入 Spring 中的自实例化对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3813588/
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
How to inject dependencies into a self-instantiated object in Spring?
提问by Igor Mukhin
Let's say we have a class:
假设我们有一个类:
public class MyClass {
@Autowired private AnotherBean anotherBean;
}
Then we created an object of this class (or some other framework have created the instance of this class).
然后我们创建了这个类的一个对象(或者其他一些框架已经创建了这个类的实例)。
MyClass obj = new MyClass();
Is it possible to still inject the dependencies? Something like:
是否仍然可以注入依赖项?就像是:
applicationContext.injectDependencies(obj);
(I think Google Guice has something like this)
(我认为 Google Guice 有这样的东西)
采纳答案by skaffman
You can do this using the autowireBean()
method of AutowireCapableBeanFactory
. You pass it an arbitrary object, and Spring will treat it like something it created itself, and will apply the various autowiring bits and pieces.
您可以使用 的autowireBean()
方法执行此操作AutowireCapableBeanFactory
。你传递给它一个任意对象,Spring 会把它当作它自己创建的东西来对待,并将应用各种自动装配的点点滴滴。
To get hold of the AutowireCapableBeanFactory
, just autowire that:
要获得AutowireCapableBeanFactory
,只需自动装配:
private @Autowired AutowireCapableBeanFactory beanFactory;
public void doStuff() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
回答by glaz666
You can also mark your MyClass with @Configurable annotation:
您还可以使用 @Configurable 注释标记您的 MyClass:
@Configurable
public class MyClass {
@Autowired private AnotherClass instance
}
Then at creation time it will automatically inject its dependencies. You also should have <context:spring-configured/>
in your application context xml.
然后在创建时它会自动注入它的依赖项。您还应该<context:spring-configured/>
在您的应用程序上下文 xml 中。
回答by rand0m86
Just got the same need and in my case it was already the logic inside non Spring manageable java class which had access to ApplicationContext
. Inspired by scaffman.
Solved by:
刚刚得到了同样的需求,在我的情况下,它已经是非 Spring 可管理的 Java 类中的逻辑,它可以访问ApplicationContext
. 灵感来自 scaffman。解决者:
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
回答by Raf
I wanted to share my solution that follows the @Configurable
approach as briefly
mentioned in @glaz666 answerbecause
我想分享我遵循@glaz666答案中提到的@Configurable
方法的解决方案,因为briefly
- The answerby @skaffman is nearly 10 years old, and that does not mean not good enough or does not work
- The answer by @glaz666 is brief and didn't really help me solve my problem but, did point me in the right direction
- @skaffman的答案已经有将近 10 年的历史了,但这并不意味着不够好或不起作用
- @glaz666 的回答很简短,并没有真正帮助我解决问题,但是确实为我指明了正确的方向
My setup
我的设置
- Spring Boot 2.0.3 with
Spring Neo4j & Aop starts
(which is irrelevant anyway) - Instantiate a bean when
Spring Boot
is ready using@Configurable
approach (usingApplicationRunner
) - Gradle & Eclipse
- Spring Boot 2.0.3 with
Spring Neo4j & Aop starts
(无论如何都无关紧要) Spring Boot
准备好时实例化一个 bean使用@Configurable
方法(使用ApplicationRunner
)- 摇篮和日食
Steps
脚步
I needed to follow the steps below in order to get it working
我需要按照以下步骤操作才能使其正常工作
- The
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false)
to be placed on top of yourBean
that is to be manually instantiated. In my case theBean
that is to be manually instantiated have@Autowired
services hence, the props to above annotation. - Annotate the Spring Boot's main
XXXApplicaiton.java
(or the file that is annotated with@SpringBootApplication
) with the@EnableSpringConfigured
and@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
- Add the dependencies in your build file (i.e. build.gradle or pom.xml depending on which one you use)
compile('org.springframework.boot:spring-boot-starter-aop')
andcompile('org.springframework:spring-aspects:5.0.7.RELEASE')
- New+up your
Bean
that is annotated with@Configurable
anywhere and its dependencies should be autowired.
- 将
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false)
放置在你的上面Bean
是手动实例化。在我的情况下Bean
,要手动实例化的@Autowired
服务因此具有上述注释的道具。 - 注释春天启动的主
XXXApplicaiton.java
(即标注有或文件@SpringBootApplication
含)@EnableSpringConfigured
和@EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
- 在您的构建文件中添加依赖项(即 build.gradle 或 pom.xml,具体取决于您使用的是哪一个)
compile('org.springframework.boot:spring-boot-starter-aop')
和compile('org.springframework:spring-aspects:5.0.7.RELEASE')
- New+up 你的
Bean
那个在@Configurable
任何地方都被注释了,它的依赖项应该是自动装配的。
*In regards to point #3 above, I am aware that the org.springframework.boot:spring-boot-starter-aop
transitively pulls the spring-aop
(as shown here mavencentral) but, in my case the Eclipse failed to resolve the @EnableSpringConfigured
annotations hence, why I explicitly added the spring-aop
dependency in addition to the starter. Should you face the same issue, just declare the dependency or go on adventure of figuring out
*关于上面的第 3 点,我知道org.springframework.boot:spring-boot-starter-aop
传递拉取spring-aop
(如这里所示mavencentral)但是,在我的情况下,Eclipse 未能解析@EnableSpringConfigured
注释,因此,为什么我spring-aop
除了 starter 之外还明确添加了依赖项。如果您遇到同样的问题,只需声明依赖项或继续冒险找出
- Is there a version conflict
- Why the
org.springframework.context.annotation.aspect.*
is not available - Is your IDE setup properly
- Etc etc.
- 是否有版本冲突
- 为什么
org.springframework.context.annotation.aspect.*
不可用 - 您的 IDE 设置是否正确
- 等等等等。