<context:component-scan/> 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。
<context:component-scan/> 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
相关阅读:spring组件扫描<context:component-scan/>使用详解
name-generator:指定产生规则
当一个 Bean 被自动检测到时,会根据那个扫描器的 BeanNameGenerator 策略生成它的 bean 名称。默认情况下,对于包含 name 属性的 @Component、@Repository、 @Service 和 @Controller,会把 name 取值作为 Bean 的名字。如果这个注解不包含 name 值或是其他被自定义过滤器发现的组件,默认 Bean 名称会是小写开头的非限定类名。如果你不想使用默认 bean 命名策略,可以提供一个自定义的命名策略。
If you do not want to rely on the default bean-naming strategy, you can provide a custom
bean-naming strategy. First, implement the BeanNameGenerator interface, and be sure to
include a default no-arg constructor. Then, provide the fully-qualified class name when
configuring the scanner:
<beans>
<context:component-scan base-package="org.example"
name-generator="org.example.MyNameGenerator" />
</beans>
实行示例
Java代码
1. package
2.
3. import
4. import
5. import
6. import
7. import
8.
9.
10. public class BeanNameGenerator extends
11.
12. private
13.
14. private
15. new
16. for (int n = 0; n < name.length(); n++) {
17. char
18. if
19. if (n > 0) {
20. '_');
21. }
22. c = Character.toLowerCase(c);
23. }
24. sb.append(c);
25. }
26. return
27. }
28.
29. @Override
30. public
31. String name;
32. String className = definition.getBeanClassName();
33.
34. final String CONTROLLER_POSTFIX = "Action";
35. if
36.
37. null;
38.
39. AnnotatedBeanDefinition annotatedDef = (AnnotatedBeanDefinition) definition;
40. AnnotationMetadata amd = annotatedDef.getMetadata();
41.
42. final String controllerAnnotation = "org.springframework.stereotype.Controller";
43. "value");
44. if (controllerName != null && controllerName.length() > 0) {
45. // explicit specified postfix
46. if (controllerName.charAt(0) == '.') {
47. suffix = controllerName;
48. }
49. // for backword compatible
50. // explicit specified struts uri
51. else if (controllerName.indexOf('.') == -1) {
52. return controllerName + ".do";
53. }
54. // explicit specified uri
55. else
56. return
57. }
58. }
59.
60. if (BASE_PACKAGE_NAME == null) {
61. 0,
62. ".web.") + ".web".length());
63. }
64.
65. int pos = className.lastIndexOf('.');
66. 1,
67. className.length() - CONTROLLER_POSTFIX.length());
68. namePart = convertJavaNameToUrlName(namePart);
69.
70. String packagePart = className.substring(BASE_PACKAGE_NAME.length(), pos);
71. if (packagePart.indexOf('_') != -1) {
72. "_.", ".");
73. }
74. assert packagePart.endsWith(".action");
75. 0, packagePart.length() - ".action".length());
76.
77. '.'
78.
79. if (name.startsWith(".app.")) {
80. ".app".length());
81. }
82.
83. // postfix specified
84. if (suffix != null) {
85. // do nothing
86. }
87. // common .do actions
88. else if (name.endsWith(".operate") ||
89. ".functions")) {
90. ".do";
91. }
92. //fall back to html
93. else
94. ".html";
95. }
96. '.', '/') + suffix;
97. }
98. else
99. super.generateBeanName(definition, registry);
100. }
101. return
102. }
103.
104. }