了解Spring @Autowired用法
我正在阅读Spring 3.0.x参考文档以了解Spring Autowired注释:
3.9.2 @Autowired和@Inject
我无法理解下面的例子。 我们是否需要在XML中进行一些操作?
例1
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
例2
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
这两个类如何实现相同的接口并使用相同的类自动装配?
例:
class Red implements Color
class Blue implements Color
class myMainClass{
@Autowired
private Color color;
draw(){
color.design();
}
}
哪种设计方法会被调用? 我如何确保Red类的设计方法被调用而不是蓝色?
@Autowired
注释允许您跳过注入内容的其他位置,只是为您做。 假设你的包是com.mycompany.movies
你必须把这个标签放在你的XML(application context file)中:
<context:component-scan base-package="com.mycompany.movies" />
该标签将执行自动扫描。 假设每个必须成为bean的类都使用@Component
(对于简单bean)或@Controller
(对于servlet控件)或@Repository
(对于DAO
类)的正确注释进行注释,并且这些类位于com.mycompany.movies
包下的某个位置com.mycompany.movies
,Spring会找到所有这些并为每个bean创建一个bean。 这是在2个类的扫描中完成的 - 它第一次只搜索需要成为bean的类并映射它需要做的注入,而在第二次扫描时它注入了bean。 当然,您可以在更传统的XML文件或@Configuration类(或三者的任意组合)中定义bean。
@Autowired
注释告诉Spring需要发生注入。 如果你把它放在setMovieFinder
方法setMovieFinder
它可以理解(通过前缀set
+ @Autowired
注解)一个bean需要被注入。 在第二次扫描中,Spring搜索一个类型为MovieFinder
的bean,如果它找到这样的bean,它将它注入到这个方法中。 如果它找到两个这样的bean,你将得到一个Exception
。 为了避免这个Exception
,你可以使用@Qualifier
注解并以下面的方式告诉它注入两个bean中的哪一个:
@Qualifier("redBean")
class Red implements Color {
// Class code here
}
@Qualifier("blueBean")
class Blue implements Color {
// Class code here
}
或者,如果您更愿意在XML中声明bean,它看起来像这样:
<bean id="redBean" class="com.mycompany.movies.Red"/>
<bean id="blueBean" class="com.mycompany.movies.Blue"/>
在@Autowired
声明中,您还需要添加@Qualifier
以指示要注入的两个颜色bean中的哪一个:
@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
this.color = color;
}
如果你不想使用两个注解( @Autowired
和@Qualifier
),你可以使用@Resource
来组合这两个注解:
@Resource(name="redBean")
public void setColor(Color color) {
this.color = color;
}
@Resource
(你可以在这个答案的第一个注释中读到关于它的一些额外的数据)让你使用两个注释,而不是只使用一个。
我只会再添加两条评论:
@Inject
而不是@Autowired
因为它不是Spring特有的,并且是JSR-330
标准的一部分。 @Inject
/ @Autowired
放在构造函数中而不是方法上。 如果将它放在构造函数中,则可以验证注入的Bean是否为空,并在尝试启动应用程序时快速失败,并在需要实际使用Bean时避免NullPointerException
。 因此,总结一下: @Autowired
注释让您无需自己在XML文件中(或以任何其他方式)进行布线,只需找到需要注入的地方,并为您做到这一点。
更新 :为了完成这个图片,我创建了一个关于@Configuration
类的新问题。
示例中没有说“实现相同接口的类”。 MovieCatalog
是一种类型,而CustomerPreferenceDao
是另一种类型。 春天很容易将它们分开。
在Spring 2.x中,bean的连线主要通过bean ID或名称进行。 Spring 3.x仍然支持这一点,但通常情况下,您将拥有一个具有特定类型的bean的实例 - 大多数服务都是单例。 为这些创建名字是很乏味的。 所以Spring开始支持“按类型自动装配”。
这些示例显示了各种可用于将Bean注入字段,方法和构造函数的方法。
XML已经包含了Spring需要的所有信息,因为您必须在每个bean中指定完全限定的类名称。 尽管如此,你需要对接口有点小心:
这种自动装配将失败:
@Autowired
public void prepare( Interface1 bean1, Interface1 bean2 ) { ... }
由于Java不会保留字节代码中的参数名称,因此Spring无法区分这两个bean。 解决方法是使用@Qualifier
:
@Autowired
public void prepare( @Qualifier("bean1") Interface1 bean1,
@Qualifier("bean2") Interface1 bean2 ) { ... }
是的,您可以配置Spring servlet上下文xml文件来定义您的bean(即类),以便它可以为您自动注入。 但是,请注意,您必须执行其他配置才能使Spring正常运行,并且最好的方法是完成一个教程。
一旦你的Spring配置好了,你可以在你的Spring servlet上下文xml文件中为上面的例子1执行以下操作(请将com.movies的包名替换为真正的包名,如果这是第三方类,然后确保相应的jar文件位于类路径中):
<beans:bean id="movieFinder" class="com.movies.MovieFinder" />
或者如果MovieFinder类有一个带有原始值的构造函数,那么你可以这样,
<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
<beans:constructor-arg value="100" />
</beans:bean>
或者如果MovieFinder类有一个期望另一个类的构造函数,那么你可以做这样的事情,
<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
<beans:constructor-arg ref="otherBeanRef" />
</beans:bean>
...其中'otherBeanRef'是另一个有预期类的引用的bean。
链接地址: http://www.djcxy.com/p/22687.html上一篇: Understanding Spring @Autowired usage
下一篇: How to inject Spring Bean for factory method requiring MyClass.class parameter