java 如何在没有 Spring XML 上下文文件的情况下自动装配对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12782000/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:11:42  来源:igfitidea点击:

How to AutoWire an object without Spring XML context file?

javaspringjakarta-eeioc-containerautowired

提问by faghani

I have an Interface with Componentannotation and some classes that implemented it as follows:

我有一个带有Component注释的接口和一些实现它的类,如下所示:

@Component
public interface A {
}

public class B implements A {
}
public class C implements A {
}

Also, I have a class with an Autowiredvariable like this:

另外,我有一个带有这样的Autowired变量的类:

public class Collector {
    @Autowired
    private Collection<A> objects;

    public Collection<A> getObjects() {
        return objects;
    }
}

My context file consists of these definitions:

我的上下文文件包含以下定义:

<context:component-scan base-package="org.iust.ce.me"></context:component-scan>

<bean id="objectCollector" class="org.iust.ce.me.Collector" autowire="byType"/>

<bean id="b" class="org.iust.ce.me.B"></bean>
<bean id="c" class="org.iust.ce.me.C"></bean>

And in the main class, I have some codes as follows:

在主类中,我有一些代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
B b = (B) context.getBean("b");
C c = (C) context.getBean("c");
Collector objectCollector = (Collector) context.getBean("objectCollector");

for (A object : objectCollector.getObjects()) {
    System.out.println(object);
}

Output:

输出:

org.iust.ce.me.B@1142196
org.iust.ce.me.C@a9255c


These codes work well, but for some reasons I'm not willing to use xml context file. Besides it, I prefer to create the objects with the newoperator rather than using the getBean()method. Nevertheless, since the AutoWiringis really good idea in programming, I don't want to lose it.

这些代码运行良好,但由于某些原因,我不愿意使用 xml 上下文文件。除此之外,我更喜欢用new操作符创建对象而不是使用getBean()方法。尽管如此,由于这AutoWiring是编程中的好主意,我不想失去它。

Now I have two questions!!

现在我有两个问题!!

  1. how can I AutoWireclasses that implements the AInterface without using the xml context file?
    Is it possible at all?

  2. when I change the scopeof a bean from singltonto prototypeas follows:

    <bean id="b" class="org.iust.ce.me.B" scope="prototype"></bean>

    and instantiate several beans of it, only the bean which was instantiated during creating context, is injectedinto AutoWiredvariable. Why?

  1. 如何AutoWireA不使用 xml 上下文文件的情况下实现接口的类?
    有可能吗?

  2. 当我将scopebean 从singlton更改 prototype为如下时:

    <bean id="b" class="org.iust.ce.me.B" scope="prototype"></bean>

    并实例数它的豆子,只就创建过程中实例化的豆context,是injectedAutoWired变量。为什么?

Any help will be appreciated.

任何帮助将不胜感激。

回答by Willy

Not sure the version of Spring you are using. But currently you can use @Configurationto replace .xml. Take a look at @Configuration

不确定您使用的 Spring 版本。但目前您可以使用@Configuration.xml 来替换。看看@Configuration

Below is the code in documentation

以下是文档中的代码

@Configuration
public class ServiceConfig {
    private @Autowired RepositoryConfig repositoryConfig;
    public @Bean TransferService transferService() {
        return new TransferServiceImpl(repositoryConfig.accountRepository());
    }
}

@Configuration
public interface RepositoryConfig {
    @Bean AccountRepository accountRepository();
}

@Configuration
public class DefaultRepositoryConfig implements RepositoryConfig {
    public @Bean AccountRepository accountRepository() {
        return new JdbcAccountRepository(...);
    }
}

@Configuration
@Import({ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete config!
public class SystemTestConfig {
    public @Bean DataSource dataSource() { /* return DataSource */ }
}
public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
    TransferService transferService = ctx.getBean(TransferService.class);
    transferService.transfer(100.00, "A123", "C456");
}

回答by marcus

Provided the classes to be managed have been correctly annotated, Spring can scan the application's files to get the information it needs without any xml or java configuration files at all.

如果要管理的类已正确注释,Spring 可以扫描应用程序的文件以获取所需的信息,而根本不需要任何 xml 或 java 配置文件。

AnnotationConfigApplicationContext  context = new AnnotationConfigApplicationContext();
context.scan("com.something.something.etc");
context.refresh();
...context.getBean("name_of_bean");

Note AnnotationConfigApplicationContextis instantiated without any arguments. context.scan("...");takes a string that tells Spring where to look. i.e. packages

NoteAnnotationConfigApplicationContext是在没有任何参数的情况下实例化的。context.scan("...");接受一个字符串,告诉 Spring 去哪里找。即包

com.something.something.etc.one
com.comething.something.etc.two
将被扫描,并与标注的那些包中的类@Component@Component@Autowired@Autowired等将instatiated并注射在需要的地方。

This approach doesn't seem to be as well documented.

这种方法似乎没有很好的记录。

回答by sgpalit

1- You need to write another class that will do the operation. write @Component to B and C class.

1-您需要编写另一个将执行操作的类。将@Component 写入 B 和 C 类。

public static void main(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");  
    InitClass initClass = (InitClass) context.getBean("initClass");  
}


public class InitClass{  
   @Autowired 
   public B b;

   @Autowired 
   public C c;
}

with this you will get B and C without using xml.

有了这个,您将在不使用 xml 的情况下获得 B 和 C。

2- http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.htmlBean scopes are detailed mentioned here. If you want always a new object you should use prototype but creating a new one will be done in different classes. In the same class you should add a new reference.

2- http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.htmlBean 范围在这里详细提到。如果你总是想要一个新对象,你应该使用原型,但创建一个新对象将在不同的类中完成。在同一个类中,您应该添加一个新的引用。

like

喜欢

public class InitClass{
    @Autowired 
    public A a1;

    @Autowired 
    public A a2;

}