Understanding Spring @Autowired usage
我正在阅读Spring3.0.x参考文档以了解SpringAutowired注释:
3.9.2@autowired和@inject
我无法理解下面的例子。我们需要在XML中做些什么才能使它工作吗?
例1
1 2 3 4 5 6 7 8 9 10 11 | public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... } |
例2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... } |
这两个类如何能够实现相同的接口并使用相同的类?
例子:
1 2 3 4 5 6 7 8 9 10 11 |
将调用哪种设计方法?如何确保调用红色类的设计方法而不是蓝色类的设计方法?
DR
@autowired注释使您无需在XML文件中自己进行连接(或以任何其他方式),只需为您找到需要注入的内容,并为您完成这些操作。
完整的解释
1 | <context:component-scan base-package="com.mycompany.movies" /> |
这个标签将自动扫描。假设必须成为bean的每个类都用正确的注释进行了注释,如
1 2 3 4 5 6 7 8 9 |
或者,如果您更愿意在XML中声明bean,它看起来应该是这样的:
1 2 3 | <bean id="redBean" class="com.mycompany.movies.Red"/> <bean id="blueBean" class="com.mycompany.movies.Blue"/> |
在
1 2 3 4 5 |
如果不想使用两个注释(
1 2 3 4 |
我再加两条评论:
更新:为了完成这张图片,我创建了一个关于
示例中没有说明"实现相同接口的类"。
在Spring2.x中,bean的连接主要通过bean id或名称进行。这仍然由Spring3.x支持,但通常情况下,您会有一个具有特定类型的bean实例——大多数服务都是单例的。为那些人创建名字是乏味的。所以弹簧开始支持"自动排线"。
示例所显示的是可以使用各种方法将bean注入到字段、方法和构造函数中。
XML已经包含了Spring需要的所有信息,因为您必须在每个bean中指定完全限定的类名。不过,您需要对接口小心一点:
自动布线将失败:
1 2 | @Autowired public void prepare( Interface1 bean1, Interface1 bean2 ) { ... } |
由于Java不保留字节码中的参数名,Spring不再能够区分两个bean。修复方法是使用
1 2 3 | @Autowired public void prepare( @Qualifier("bean1") Interface1 bean1, @Qualifier("bean2") Interface1 bean2 ) { ... } |
是的,您可以配置SpringServlet上下文XML文件来定义bean(即类),以便它可以为您进行自动注入。但是,请注意,您必须执行其他配置才能启动和运行,最好的方法是遵循教程的基础知识。
可能配置了Spring之后,可以在Spring Servlet上下文XML文件中执行以下操作(例如1)以工作(请将com.movies的包名称替换为真正的包名称,如果这是第三方类,请确保类路径上有适当的JAR文件):
1 | <beans:bean id="movieFinder" class="com.movies.MovieFinder" /> |
或者如果moviefinder类有一个带有基元值的构造函数,那么您可以这样做,
1 2 3 | <beans:bean id="movieFinder" class="com.movies.MovieFinder"> <beans:constructor-arg value="100" /> </beans:bean> |
或者如果moviefinder类有一个构造函数需要另一个类,那么您可以这样做,
1 2 3 | <beans:bean id="movieFinder" class="com.movies.MovieFinder"> <beans:constructor-arg ref="otherBeanRef" /> </beans:bean> |
…其中"otherBeanRef"是另一个引用了预期类的bean。