Spring 可以在抽象类中自动装配吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19965829/
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
Spring can you autowire inside an abstract class?
提问by stackoverflow
Spring is failing to autowire my object? Is it possible to autowire an object within an abstract class. Assume all schemas are supplied in application-context.xml
Spring 无法自动装配我的对象?是否可以在抽象类中自动装配对象。假设所有模式都在 application-context.xml 中提供
Question: What annotation should be on the base and extending classes (if any) @Service @Component?
问题:基类和扩展类(如果有)@Service @Component 上应该有什么注解?
Example
例子
abstract class SuperMan {
@Autowire
private DatabaseService databaseService;
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
Extending class
扩展类
public class SuperGirl extends SuperMan {
@Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
application-context.xml
应用程序上下文.xml
<context:component-scan base-package="com.baseLocation" />
<context:annotation-config/>
采纳答案by Andrei Nicusan
Normally, Spring should do the autowiring, as long as your abstract class is in the base-package provided for component scan.
通常,Spring 应该进行自动装配,只要您的抽象类位于为组件扫描提供的基础包中。
See thisand thisfor further reference.
@Service
and @Component
are both stereotypes that creates beans of the annotated type inside the Spring container. As Spring Docs state,
@Service
和@Component
都是在 Spring 容器内创建带注释类型的 bean 的构造型。正如 Spring Docs 所说,
This annotation serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning.
该注解作为@Component 的特化,允许通过类路径扫描自动检测实现类。
回答by Frederic Close
I have that kind of spring setup working
我有那种弹簧装置工作
an abstract class with an autowired field
具有自动装配字段的抽象类
public abstract class AbstractJobRoute extends RouteBuilder {
@Autowired
private GlobalSettingsService settingsService;
and several children defined with @Component
annotation.
和几个用@Component
注释定义的孩子。
回答by Muhammed Ozdogan
What if you need any database operation in SuperGirl
you would inject it again into SuperGirl
.
如果你需要任何数据库操作,SuperGirl
你会再次将它注入到SuperGirl
.
I think the main idea is using the same object reference in different classes. So what about this:
我认为主要思想是在不同的类中使用相同的对象引用。那么这个呢:
//There is no annotation about Spring in the abstract part.
abstract class SuperMan {
private final DatabaseService databaseService;
public SuperMan(DatabaseService databaseService) {
this.databaseService = databaseService;
}
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
@Component
public class SuperGirl extends SuperMan {
private final DatabaseService databaseService;
@Autowired
public SuperGirl (DatabaseService databaseService) {
super(databaseService);
this.databaseService = databaseService;
}
@Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
In my opinion, inject once run everywhere :)
在我看来,注入一次到处运行:)
回答by user1295235
In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:
就我而言,在 Spring4 应用程序中,我必须使用经典的抽象工厂模式(为此我从 - http://java-design-patterns.com/patterns/abstract-factory/ 中获取了想法)来创建每个实例每次有一个操作要完成。所以我的代码设计如下:
public abstract class EO {
@Autowired
protected SmsNotificationService smsNotificationService;
@Autowired
protected SendEmailService sendEmailService;
...
protected abstract void executeOperation(GenericMessage gMessage);
}
public final class OperationsExecutor {
public enum OperationsType {
ENROLL, CAMPAIGN
}
private OperationsExecutor() {
}
public static Object delegateOperation(OperationsType type, Object obj)
{
switch(type) {
case ENROLL:
if (obj == null) {
return new EnrollOperation();
}
return EnrollOperation.validateRequestParams(obj);
case CAMPAIGN:
if (obj == null) {
return new CampaignOperation();
}
return CampaignOperation.validateRequestParams(obj);
default:
throw new IllegalArgumentException("OperationsType not supported.");
}
}
}
@Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
@Override
public void executeOperation(GenericMessage genericMessage) {
LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
}
}
Initially to inject the dependencies in the abstract class I tried all stereotype annotations like @Component, @Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **@Configurable(dependencyCheck = true)**
annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.
最初为了在抽象类中注入依赖项,我尝试了所有构造型注释,如 @Component、@Service 等,但即使 Spring 上下文文件对整个包具有 ComponentScanning,但不知何故在创建子类的实例(如 CampaignOperation)时,超级抽象类 EO 是将其属性设为 null,因为 spring 无法识别和注入其依赖项。经过多次反复试验,我使用了此**@Configurable(dependencyCheck = true)**
注释,最后 Spring 能够注入依赖项,并且我能够使用子类中的属性而不会将它们弄乱许多属性。
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
I also tried these other references to find a solution:
我还尝试了这些其他参考资料以找到解决方案:
- http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
- http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
- https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
- http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
- https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
- Using abstract factory with Spring framework
- Spring Autowiring not working for Abstract classes
- Inject spring dependency in abstract super class
- Spring and Abstract class - injecting properties in abstract classes
- http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
- http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
- https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
- http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
- https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
- 在 Spring 框架中使用抽象工厂
- Spring Autowiring 不适用于抽象类
- 在抽象超类中注入 spring 依赖
- Spring 和抽象类 - 在抽象类中注入属性
Please try using **@Configurable(dependencyCheck = true)**
and update this post, I might try helping you if you face any problems.
请尝试使用**@Configurable(dependencyCheck = true)**
并更新此帖子,如果您遇到任何问题,我可能会尝试帮助您。