之间的区别和<上下文:组件扫描>

发布于 2024-12-04 09:41:25 字数 586 浏览 1 评论 0 原文

我正在学习 Spring 3,但我似乎没有掌握 背后的功能;

从我读到的内容来看,它们似乎处理不同的注释@Required@Autowired等与@Component@Repository@Service 等),而且从我读到的内容来看,它们注册了相同的 bean 后处理器 类。

更让我困惑的是, 上有一个 annotation-config 属性

有人可以解释一下这些标签吗?什么是相似的,什么是不同的,一个被另一个取代了,它们是否相互补充,我需要其中之一还是两者都需要?

I'm learning Spring 3 and I don't seem to grasp the functionality behind <context:annotation-config> and <context:component-scan>.

From what I've read they seem to handle different annotations (@Required, @Autowired etc vs @Component, @Repository, @Service etc), but also from what I've read, they register the same bean post processor classes.

To confuse me even more, there is an annotation-config attribute on <context:component-scan>.

Can someone shed some light on these tags? What's similar and what's different, is one superseded by the other, do they complete each other, do I need one of them or both?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

爱给你人给你 2024-12-11 09:41:25

用于激活已在应用程序上下文中注册的 bean 中的注释(无论它们是使用 XML 还是通过包扫描定义的)。

也可以执行 的操作,但 > 还扫描包以在应用程序上下文中查找并注册 bean。

我将使用一些例子来展示差异/相似之处。

让我们从 ABC 类型的三个 Bean 的基本设置开始,其中 B >C 被注入到 A 中。

package com.xxx;
public class B {
  public B() {
    System.out.println("creating bean B: " + this);
  }
}

package com.xxx;
public class C {
  public C() {
    System.out.println("creating bean C: " + this);
  }
}

package com.yyy;
import com.xxx.B;
import com.xxx.C;
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc; 
  }
}

使用以下 XML 配置:

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A">
  <property name="bbb" ref="bBean" />
  <property name="ccc" ref="cBean" />
</bean>

加载上下文会产生以下输出:

creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6

好的​​,这是预期的输出。但这是“旧式”春天。现在我们有了注释,所以让我们使用它们来简化 XML。

首先,让我们自动装配 bean A 上的 bbbccc 属性,如下所示:

package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxx.B;
import com.xxx.C;
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  @Autowired
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  @Autowired
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc;
  }
}

这允许我从 XML 中删除以下行:

<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />

My XML现在简化为:

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

当我加载上下文时,我得到以下输出:

creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf

好的​​,这是错误的!发生了什么?为什么我的属性没有自动连接?

嗯,注释是一个很好的功能,但它们本身没有任何作用。他们只是注释一些东西。您需要一个处理工具来查找注释并对其进行处理。

来救援。这将激活它在定义其本身的同一应用程序上下文中定义的 bean 上找到的注释的操作。

如果我将 XML 更改为:

<context:annotation-config />
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

当我加载应用程序上下文时,我会得到正确的结果:

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b

好的,这很好,但我从 XML 中删除了两行并添加了一行。这并不是很大的区别。使用注释的想法是它应该删除 XML。

因此,让我们删除 XML 定义并将它们全部替换为注释:

package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class B {
  public B() {
    System.out.println("creating bean B: " + this);
  }
}

package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class C {
  public C() {
    System.out.println("creating bean C: " + this);
  }
}

package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xxx.B;
import com.xxx.C;
@Component
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  @Autowired
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  @Autowired
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc;
  }
}

而在 XML 中,我们只保留以下内容:

<context:annotation-config />

我们加载上下文,结果是...什么也没有。不会创建任何 Bean,也不会自动装配 Bean。没有什么!

这是因为,正如我在第一段中所说, 仅适用于在应用程序上下文中注册的 bean。因为我删除了三个 bean 的 XML 配置,所以没有创建任何 bean,并且 没有要处理的“目标”。

但这对于可以扫描包以查找要处理的“目标”的 来说不是问题。让我们将 XML 配置的内容更改为以下条目:

<context:component-scan base-package="com.xxx" />

当我加载上下文时,我得到以下输出:

creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff

嗯...缺少一些东西。为什么?

如果仔细观察这些类,会发现类 A 具有包 com.yyy,但我已在 中指定> 使用包com.xxx,所以这完全错过了我的A类,只选择了BC位于 com.xxx 包中。

为了解决这个问题,我还添加了另一个包:

<context:component-scan base-package="com.xxx,com.yyy" />

现在我们得到了预期的结果:

creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9

就是这样!现在您不再拥有 XML 定义,而是拥有注释。

作为最后一个示例,保留带注释的类 ABC 并将以下内容添加到 XML 中,加载后我们会得到什么语境?

<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

我们仍然得到正确的结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

即使没有通过扫描获取类A的bean,处理工具仍然由应用在所有已注册的 bean 上
在应用程序上下文中,即使对于在 XML 中手动注册的 A 也是如此。

但是,如果我们有以下 XML,我们会得到重复的 bean 吗,因为我们同时指定了 < /代码>?

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

不,没有重复,我们再次得到了预期的结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

这是因为两个标签注册了相同的处理工具(如果 )指定了 component-scan>),但 Spring 只负责运行它们一次。

即使您自己多次注册处理工具,Spring 仍然会确保它们只发挥其魔力一次;这个 XML:

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />

仍然会生成以下结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

好的,这就结束了。

我希望这些信息以及 @Tomasz Nurkiewicz 和 @Sean Patrick Floyd 的回复足以让您了解如何
有效。

<context:annotation-config> is used to activate annotations in beans already registered in the application context (no matter if they were defined with XML or by package scanning).

<context:component-scan> can also do what <context:annotation-config> does but <context:component-scan> also scans packages to find and register beans within the application context.

I'll use some examples to show the differences/similarities.

Let's start with a basic setup of three beans of type A, B and C, with B and C being injected into A.

package com.xxx;
public class B {
  public B() {
    System.out.println("creating bean B: " + this);
  }
}

package com.xxx;
public class C {
  public C() {
    System.out.println("creating bean C: " + this);
  }
}

package com.yyy;
import com.xxx.B;
import com.xxx.C;
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc; 
  }
}

With the following XML configuration :

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A">
  <property name="bbb" ref="bBean" />
  <property name="ccc" ref="cBean" />
</bean>

Loading the context produces the following output:

creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6

OK, this is the expected output. But this is "old style" Spring. Now we have annotations so let's use those to simplify the XML.

First, lets autowire the bbb and ccc properties on bean A like so:

package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxx.B;
import com.xxx.C;
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  @Autowired
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  @Autowired
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc;
  }
}

This allows me to remove the following rows from the XML:

<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />

My XML is now simplified to this:

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

When I load the context I get the following output:

creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf

OK, this is wrong! What happened? Why aren't my properties autowired?

Well, annotations are a nice feature but by themselves, they do nothing whatsoever. They just annotate stuff. You need a processing tool to find the annotations and do something with them.

<context:annotation-config> to the rescue. This activates the actions for the annotations that it finds on the beans defined in the same application context where itself is defined.

If I change my XML to this:

<context:annotation-config />
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

when I load the application context I get the proper result:

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b

OK, this is nice, but I've removed two rows from the XML and added one. That's not a very big difference. The idea with annotations is that it's supposed to remove the XML.

So let's remove the XML definitions and replace them all with annotations:

package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class B {
  public B() {
    System.out.println("creating bean B: " + this);
  }
}

package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class C {
  public C() {
    System.out.println("creating bean C: " + this);
  }
}

package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xxx.B;
import com.xxx.C;
@Component
public class A { 
  private B bbb;
  private C ccc;
  public A() {
    System.out.println("creating bean A: " + this);
  }
  @Autowired
  public void setBbb(B bbb) {
    System.out.println("setting A.bbb with " + bbb);
    this.bbb = bbb;
  }
  @Autowired
  public void setCcc(C ccc) {
    System.out.println("setting A.ccc with " + ccc);
    this.ccc = ccc;
  }
}

While in the XML we only keep this:

<context:annotation-config />

We load the context and the result is... Nothing. No beans are created, no beans are autowired. Nothing!

That's because, as I said in the first paragraph, the <context:annotation-config /> only works on beans registered within the application context. Because I removed the XML configuration for the three beans there is no bean created and <context:annotation-config /> has no "targets" to work on.

But that won't be a problem for <context:component-scan> which can scan a package for "targets" to work on. Let's change the content of the XML config into the following entry:

<context:component-scan base-package="com.xxx" />

When I load the context I get the following output:

creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff

Hmmmm... something is missing. Why?

If you look closely at the classes, class A has package com.yyy but I've specified in the <context:component-scan> to use package com.xxx so this completely missed my A class and only picked up B and C which are on the com.xxx package.

To fix this, I add this other package also:

<context:component-scan base-package="com.xxx,com.yyy" />

and now we get the expected result:

creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9

And that's it! Now you don't have XML definitions anymore, you have annotations.

As a final example, keeping the annotated classes A, B and C and adding the following to the XML, what will we get after loading the context?

<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

We still get the correct result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

Even if the bean for class A isn't obtained by scanning, the processing tools are still applied by <context:component-scan> on all beans registered
in the application context, even for A which was manually registered in the XML.

But what if we have the following XML, will we get duplicated beans because we've specified both <context:annotation-config /> and <context:component-scan>?

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

No, no duplications, We again get the expected result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

That's because both tags register the same processing tools (<context:annotation-config /> can be omitted if <context:component-scan> is specified) but Spring takes care of running them only once.

Even if you register the processing tools yourself multiple times, Spring will still make sure they do their magic only once; this XML:

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />

will still generate the following result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

OK, that about wraps it up.

I hope this information along with the responses from @Tomasz Nurkiewicz and @Sean Patrick Floyd are all you need to understand how
<context:annotation-config> and <context:component-scan> work.

酒浓于脸红 2024-12-11 09:41:25

我发现了这个很好的摘要,其中注释由哪些声明选取。通过研究你会发现 识别 识别的注释的超集,即:

  • @Component、@Service、@Repository、@Controller、@Endpoint
  • @配置@Bean@Lazy@Scope@Order@Primary@Profile@DependsOn@Import@ImportResource

如您所见 > 扩展 具有 CLASSPATH 组件扫描和 Java @Configuration 功能。

I found this nice summary of which annotations are picked up by which declarations. By studying it you will find that <context:component-scan/> recognizes a superset of annotations recognized by <context:annotation-config/>, namely:

  • @Component, @Service, @Repository, @Controller, @Endpoint
  • @Configuration, @Bean, @Lazy, @Scope, @Order, @Primary, @Profile, @DependsOn, @Import, @ImportResource

As you can see <context:component-scan/> logically extends <context:annotation-config/> with CLASSPATH component scanning and Java @Configuration features.

萤火眠眠 2024-12-11 09:41:25

Spring 允许您做两件事:

  1. 自动装配 beans
  2. 自动发现 beans

1。自动装配
通常在applicationContext.xml中定义bean,其他bean使用以下方式连接
构造函数或设置方法。您可以使用 XML 或注释来连接 bean。
如果您使用注释,则需要激活注释并且必须添加
applicationContext.xml 中的 。这将简化
applicationContext.xml 中的标记结构,因为您不必手动连接 bean(构造函数或 setter)。您可以使用@Autowire注释,bean将按类型连接。

摆脱手动 XML 配置的一个进步是

2。自动发现
自动发现进一步简化了 XML,从某种意义上说,您甚至不需要在 applicationContext.xml 中添加 标记。您只需使用以下注释之一标记特定的 bean,Spring 就会自动将标记的 bean 及其依赖项连接到 Spring 容器中。注解如下:@Controller@Service@Component@Repository。通过使用 并指向基础包,Spring 将自动发现组件并将其连接到 Spring 容器中。


结论:

  • 使用 是为了能够使用
    @Autowired注解
  • 用于确定搜索
    特定的bean和自动装配的尝试。

Spring allows you to do two things:

  1. Autowiring of beans
  2. Autodiscovery of beans

1. Autowiring
Usually in applicationContext.xml you define beans and other beans are wired using
constructor or setter methods. You can wire beans using XML or annotations.
In case you use annotations, you need to activate annotations and you have to add
<context:annotation-config /> in applicationContext.xml. This will simplify the
structure of the tag from applicationContext.xml, because you will not have to manually wire beans (constructor or setter). You can use @Autowire annotation and the beans will be wired by type.

A step forward for escaping the manual XML configuration is

2. Autodiscovery
Autodiscovery is simplifying the XML one step further, in the sense that you don't even need too add the <bean> tag in applicationContext.xml. You just mark the specific beans with one of the following annotation and Spring will automatically wire the marked beans and their dependencies into the Spring container. The annotations are as follow: @Controller, @Service, @Component, @Repository. By using <context:component-scan> and pointing the base package, Spring will auto-discover and wire the components into Spring container.


As a conclusion:

  • <context:annotation-config /> is used in order to be able to use
    @Autowired annotation
  • <context:component-scan /> is used to determine the search of
    specific beans and attempt of autowiring.
罗罗贝儿 2024-12-11 09:41:25

激活 bean 中的许多不同注释,无论它们是在 XML 中定义还是通过组件扫描定义。

用于在不使用 XML 的情况下定义 beans

有关详细信息,请阅读:

<context:annotation-config> activates many different annotations in beans, whether they are defined in XML or through component scanning.

<context:component-scan> is for defining beans without using XML

For further information, read:

无远思近则忧 2024-12-11 09:41:25

: 扫描并激活 spring config xml 中已注册 bean 的注释。

: Bean 注册 +


@Autowired 和 @Required< /strong> 是目标属性级别,因此 bean 应该在使用这些注释之前在 Spring IOC 中注册。要启用这些注释,必须注册相应的 bean 或包含 。即 仅适用于已注册的 bean。

@Required 启用 RequiredAnnotationBeanPostProcessor 处理工具
@Autowired启用AutowiredAnnotationBeanPostProcessor处理工具

注意:Annotation本身无关,我们需要一个Processing Tool,也就是下面有一个类,负责核心流程。


@Repository、@Service 和 @Controller 是 @Component,它们针对类水平。

它扫描包并查找并注册 bean,它包括 完成的工作。

将 XML 迁移到注释

<context:annotation-config>: Scanning and activating annotations for already registered beans in spring config xml.

<context:component-scan>: Bean registration + <context:annotation-config>


@Autowired and @Required are targets property level so bean should register in spring IOC before use these annotations. To enable these annotations either have to register respective beans or include <context:annotation-config />. i.e. <context:annotation-config /> works with registered beans only.

@Required enables RequiredAnnotationBeanPostProcessor processing tool
@Autowired enables AutowiredAnnotationBeanPostProcessor processing tool

Note: Annotation itself nothing to do, we need a Processing Tool, which is a class underneath, responsible for the core process.


@Repository, @Service and @Controller are @Component, and they targets class level.

<context:component-scan> it scans the package and find and register the beans, and it includes the work done by <context:annotation-config />.

Migrating XML to Annotations

甜扑 2024-12-11 09:41:25

两者之间的区别真的很简单!

<context:annotation-config /> 

使您能够使用仅限于连接 bean 的属性和构造函数的注释!。

Where as

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

启用 可以执行的所有操作,并添加使用构造型,例如..@Component@Service@Repository。因此,您可以连接整个 bean,而不仅限于构造函数或属性!。

The difference between the two is really simple!.

<context:annotation-config /> 

Enables you to use annotations that are restricted to wiring up properties and constructors only of beans!.

Where as

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

Enables everything that <context:annotation-config /> can do, with addition of using stereotypes eg.. @Component, @Service , @Repository. So you can wire entire beans and not just restricted to constructors or properties!.

凶凌 2024-12-11 09:41:25
<context:annotation-config>

解析@Autowired@Qualifer注解,仅此而已,关于依赖注入,还有其他做同样工作的注释,我想如何@Inject,但都是通过注释来解析DI。

请注意,即使您已经声明了 元素,您也必须声明您的类如何成为 Bean,请记住我们有三个可用的

  • XML 选项:
  • @Annotations: @Component, @Service, @Repository, @Controller
  • JavaConfig: @Configuration, @Bean

Now with

<context:component-scan>

它做了两件事:

  • 它扫描所有带有注释的类
    @Component、@Service、@Repository、@Controller 和 @Configuration 并创建一个 Bean
  • 它与 执行相同的工作。

因此,如果您声明 ,则不再需要声明

这就是全部

一个常见的场景是例如通过 XML 只声明一个 bean 并通过注释解析 DI,例如

<bean id="serviceBeanA" class="com.something.CarServiceImpl" />
<bean id="serviceBeanB" class="com.something.PersonServiceImpl" />
<bean id="repositoryBeanA" class="com.something.CarRepository" />
<bean id="repositoryBeanB" class="com.something.PersonRepository" />

我们只声明了 bean,没有关于 < ;property>,DI通过@Autowired配置在自己的类中。这意味着服务将 @Autowired 用于其存储库组件,而存储库将 @Autowired 用于 JdbcTemplate、DataSource 等组件。

<context:annotation-config>

Only resolves the @Autowired and @Qualifer annotations, that's all, it about the Dependency Injection, There are other annotations that do the same job, I think how @Inject, but all about to resolve DI through annotations.

Be aware, even when you have declared the <context:annotation-config> element, you must declare your class how a Bean anyway, remember we have three available options

  • XML: <bean>
  • @Annotations: @Component, @Service, @Repository, @Controller
  • JavaConfig: @Configuration, @Bean

Now with

<context:component-scan>

It does two things:

  • It scans all the classes annotated with
    @Component, @Service, @Repository, @Controller and @Configuration and create a Bean
  • It does the same job how <context:annotation-config> does.

Therefore if you declare <context:component-scan>, is not necessary anymore declare <context:annotation-config> too.

Thats all

A common scenario was for example declare only a bean through XML and resolve the DI through annotations, for example

<bean id="serviceBeanA" class="com.something.CarServiceImpl" />
<bean id="serviceBeanB" class="com.something.PersonServiceImpl" />
<bean id="repositoryBeanA" class="com.something.CarRepository" />
<bean id="repositoryBeanB" class="com.something.PersonRepository" />

We have only declared the beans, nothing about <constructor-arg> and <property>, the DI is configured in their own classes through @Autowired. It means the Services use @Autowired for their Repositories components and the Repositories use @Autowired for the JdbcTemplate, DataSource etc..components

趴在窗边数星星i 2024-12-11 09:41:25

标签告诉 Spring 扫描代码库以自动解决包含 @Autowired 注释的类的依赖关系要求。

Spring 2.5 还添加了对 JSR-250 注解的支持,例如 @Resource、@PostConstruct 和 @PreDestroy。使用这些注解还需要在 Spring 容器中注册某些 BeanPostProcessor。与往常一样,它们可以注册为单独的 bean 定义,但也可以通过在 spring 配置中包含 标签来隐式注册它们。

取自 Spring 文档 基于注释的配置


Spring 提供了以下功能自动检测“构造型”类并向 ApplicationContext 注册相应的 BeanDefinition。

根据org.springframework.stereotype:

构造型是表示类型或方法在整个架构中的角色的注释(在概念层面,而不是实现层面)。
示例:@Controller @Service @Repository 等。
这些旨在供工具和方面使用(成为切入点的理想目标)。

要自动检测此类“构造型”类,需要 标记。

标记还告诉 Spring 扫描指定包(及其所有子包)下的可注入 bean 的代码。

The <context:annotation-config> tag tells Spring to scan the codebase for automatically resolving dependency requirements of the classes containing @Autowired annotation.

Spring 2.5 also adds support for JSR-250 annotations such as @Resource, @PostConstruct, and @PreDestroy.Use of these annotations also requires that certain BeanPostProcessors be registered within the Spring container. As always, these can be registered as individual bean definitions, but they can also be implicitly registered by including <context:annotation-config> tag in spring configuration.

Taken from Spring documentation of Annotation Based Configuration


Spring provides the capability of automatically detecting 'stereotyped' classes and registering corresponding BeanDefinitions with the ApplicationContext.

According to javadoc of org.springframework.stereotype:

Stereotypes are Annotations denoting the roles of types or methods in the overall architecture (at a conceptual, rather than implementation, level).
Example: @Controller @Service @Repository etc.
These are intended for use by tools and aspects (making an ideal target for pointcuts).

To autodetect such 'stereotype' classes, <context:component-scan> tag is required.

The <context:component-scan> tag also tells Spring to scan the code for injectable beans under the package (and all its subpackages) specified.

久随 2024-12-11 09:41:25
<context:component-scan /> implicitly enables <context:annotation-config/>

尝试在您的配置中使用 @Service, @Repository, @Component 工作正常,但 @Autowired、@Resource@Inject 不起作用。

这意味着 AutowiredAnnotationBeanPostProcessor 将不会启用,Spring 容器将不会处理自动装配注释。

<context:component-scan /> implicitly enables <context:annotation-config/>

try with <context:component-scan base-package="..." annotation-config="false"/> , in your configuration @Service, @Repository, @Component works fine, but @Autowired,@Resource and @Inject doesn't work.

This means AutowiredAnnotationBeanPostProcessor will not be enabled and Spring container will not process the Autowiring annotations.

一腔孤↑勇 2024-12-11 09:41:25
<context:annotation-config/> <!-- is used to activate the annotation for beans -->
<context:component-scan base-package="x.y.MyClass" /> <!-- is for the Spring IOC container to look for the beans in the base package. -->

另一个需要注意的要点是,context:component-scan 隐式调用 context:annotation-config 来激活 bean 上的注释。如果您不希望 context:component-scan 为您隐式激活注释,您可以继续设置 context:component-scan 的annotation-config 元素为

总结一下:

<context:annotation-config/> <!-- activates the annotations --> 
<context:component-scan base-package="x.y.MyClass" /> <!-- activates the annotations + register the beans by looking inside the base-package -->
<context:annotation-config/> <!-- is used to activate the annotation for beans -->
<context:component-scan base-package="x.y.MyClass" /> <!-- is for the Spring IOC container to look for the beans in the base package. -->

The other important point to note is that context:component-scan implicitly calls the context:annotation-config to activate the annotations on beans. Well if you don't want context:component-scan to implicitly activate annotations for you, you can go on setting the annotation-config element of the context:component-scan to false.

To summarize:

<context:annotation-config/> <!-- activates the annotations --> 
<context:component-scan base-package="x.y.MyClass" /> <!-- activates the annotations + register the beans by looking inside the base-package -->
君勿笑 2024-12-11 09:41:25

这个是用来告诉容器我的包里有bean类,扫描这些bean类。为了通过 bean 顶部的容器扫描 bean 类,我们必须编写如下所示的立体类型注释之一。

@Component@Service@Repository@Controller

如果我们不想在 XML 中显式编写 bean 标签,那么容器如何知道 bean 中是否存在自动装配。这可以通过使用 @Autowired 注释来实现。我们必须通过 context:annotation-config 通知容器我的 bean 中有自动装配。

<context:component-scan base-package="package name" />:

This is used to tell the container that there are bean classes in my package scan those bean classes. In order to scan bean classes by container on top of the bean we have to write one of the stereo type annotation like following.

@Component, @Service, @Repository, @Controller

<context:annotation-config />:

If we don't want to write bean tag explicitly in XML then how the container knows if there is a auto wiring in the bean. This is possible by using @Autowired annotation. we have to inform to the container that there is auto wiring in my bean by context:annotation-config.

黄昏下泛黄的笔记 2024-12-11 09:41:25

自定义标记除了扫描 java 包并从类路径注册 bean 定义的主要职责之外,还注册与 相同的一组 bean 定义。

如果由于某种原因要避免注册默认 bean 定义,则方法是在组件扫描中指定附加的“annotation-config”属性,如下所示:

<context:component-scan basePackages="" annotation-config="false"/>

参考:
http://www.java-allandsundry.com/2012/12 /contextcomponent-scan-contextannotation.html

A <context:component-scan/> custom tag registers the same set of bean definitions as is done by , apart from its primary responsibility of scanning the java packages and registering bean definitions from the classpath.

If for some reason this registration of default bean definitions are to be avoided, the way to do that is to specify an additional "annotation-config" attribute in component-scan, this way:

<context:component-scan basePackages="" annotation-config="false"/>

Reference:
http://www.java-allandsundry.com/2012/12/contextcomponent-scan-contextannotation.html

朕就是辣么酷 2024-12-11 09:41:25

这告诉Spring我将使用带注释的bean作为spring bean,并且这些bean将通过@Autowired注释连接,而不是声明在 spring 配置 xml 文件中。

这告诉 Spring 容器从哪里开始搜索那些带注释的 bean。这里spring会搜索基础包的所有子包。

<context:annotation-config>:

This tells Spring that I am going to use Annotated beans as spring bean and those would be wired through @Autowired annotation, instead of declaring in spring config xml file.

<context:component-scan base-package="com.test..."> :

This tells Spring container, where to start searching those annotated beans. Here spring will search all sub packages of the base package.

辞别 2024-12-11 09:41:25

您可以在 spring 上下文架构文件中找到更多信息。
以下是 spring-context-4.3.xsd

<conxtext:annotation-config />
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB 3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.

Note: This tag does not activate processing of Spring's @Transactional or EJB 3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
<context:component-scan>
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository, @Service, @Controller, @RestController, @ControllerAdvice, and @Configuration stereotypes    will be detected.

Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.

Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definitions
being registered; Spring's PropertySourcesPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.

you can find more information in spring context schema file.
following is in spring-context-4.3.xsd

<conxtext:annotation-config />
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB 3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.

Note: This tag does not activate processing of Spring's @Transactional or EJB 3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
<context:component-scan>
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository, @Service, @Controller, @RestController, @ControllerAdvice, and @Configuration stereotypes    will be detected.

Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.

Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definitions
being registered; Spring's PropertySourcesPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.
甜宝宝 2024-12-11 09:41:25

作为补充,您可以使用@ComponentScan以注释的方式使用

它也在 中进行了描述spring.io

配置组件扫描指令以供使用
@配置类。提供与 Spring XML 并行的支持
元素。

需要注意的一件事是,如果您使用 Spring Boot,则可以通过使用 @SpringBootApplication 注解来隐含 @Configuration 和 @ComponentScan。

As a complementary, you can use @ComponentScan to use <context:component-scan> in annotation way.

It's also described at spring.io

Configures component scanning directives for use with
@Configuration classes. Provides support parallel with Spring XML's
element.

One thing to note, if you're using Spring Boot, the @Configuration and @ComponentScan can be implied by using @SpringBootApplication annotation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文