我正在阅读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类的设计方法被调用而不是Blue?
TL; DR
@Autowired注释使你无需在XML文件中(或以任何其他方式)自行进行布线,而只是为你找到需要注入的内容,然后为你完成。
完整说明
该@Autowired注释允许你对什么注入其他地方跳过配置,只是它给你的。假设你的软件包是com.mycompany.movies你必须将此标记放入XML(应用程序上下文文件)中:
<context:component-scan base-package="com.mycompany.movies" />
该标签将进行自动扫描。假设必须成为Bean的每个类都使用正确的注释@Component(例如(对于简单bean)或@Controller(对于servlet控件)或@Repository(对于DAO类))进行注释,并且这些类位于包的某个位置com.mycompany.movies,Spring将查找所有这些并创建每个豆一个。这是通过对类的2次扫描完成的-第一次是它仅搜索需要成为bean的类并映射它需要进行的注入,而在第二次扫描中,它将注入bean。当然,你可以在更传统的XML文件中或使用@Configuration类(或这三种的任意组合)来定义bean 。
@Component
@Controller
@Repository
com.mycompany.movies,Spring
该@Autowired注解告诉Spring去哪里注射需要发生。如果将其放在方法上,setMovieFinder它将理解(通过前缀set+ @Autowired注释)需要注入bean。在第二次扫描中,Spring搜索类型为的bean MovieFinder,如果找到该bean,则将其注入此方法。如果它找到两个这样的豆,你将得到一个Exception。为了避免Exception,你可以使用@Qualifier注释,并通过以下方式告诉它注入两个bean中的哪个:
@Autowired
setMovieFinder
set+ @Autowired
bean
Spring
bean MovieFinder
Exception
@Qualifier
@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不是null,并且在尝试启动应用程序时会快速失败,并NullPointerException在需要实际使用Bean时避免出现。
@Inject
JSR-330
@Inject/ @Autowired
NullPointerException