bean注入与装配的方式有很多种,可以通过xml,get/set方式,构造函数或者注解等。简单易用的方式就是使用Spring的注解,Spring提供了大量的注解方式。
@Required注解
@Required应用于bean属性setter方法。此注解表示必须在配置时使用bean定义中的显式属性值或使用自动装配填充受影响的bean属性。如果尚未填充受影响的bean属性,则容器将抛出BeanInitializationException。
在产品级别的应用中,IoC容器可能声明了数十万了bean,bean与bean之间有着复杂的依赖关系。设置注解方法的短板之一就是验证所有的属性是否被注解是一项十分困难的操作。可以通过在<bean>中设置“dependency-check”来解决这个问题。
在应用程序的生命周期中,你可能不大愿意花时间在验证所有bean的属性是否按照上下文文件正确配置。或者你宁可验证某个bean的特定属性是否被正确的设置。即使是用“dependency-check”属性也不能很好的解决这个问题,在这种情况下,你需要使用@Required注解。
示例:
public class Employee{
private String name;
@Required
public void setName(String name){
this.name=name;
}
public string getName(){
return name;
}
}
RequiredAnnotationBeanPostProcessor是Spring中的后置处理用来验证被@Required注解的bean属性是否被正确的设置了。在使用RequiredAnnotationBeanPostProcessor来验证bean属性之前,首先要在IoC容器中对其进行注册:
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
但是如果没有属性被用@Required注解过的话,后置处理器会抛出一个BeanInitializationException异常。
@Autowired注解
@Autowired可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在setter方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配bean。默认情况下,它是类型驱动的注入。
比如,可以在设值方法上使用@Autowired注解来替代配置文件中的<property>元素。当Spring容器在setter方法上找到@Autowired注解时,会尝试用byType自动装配。
public class Employee{
private String name;
@Autowired
public void setName(String name){
this.name=name;
}
public string getName(){
return name;
}
}
当然我们也可以在构造方法上使用@Autowired注解。带有@Autowired注解的构造方法意味着在创建一个bean时将会被自动装配,即便在配置文件中使用<constructor-arg>元素。
public class TextEditor{
private SpellChecker spellChecker;
@Autowired
public TextEditor(SpellChecker spellChecker){
System.out.println("Inside TextEditor constructor.");
this.spellChecker=spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
下面是没有构造参数的配置方式:
<beans>
<context:annotation-config/>
<!--Definition for textEditor bean without constructor-arg-->
<bean id="textEditor" class="com.howtodoinjava.TextEditor"/>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="com.howtodoinjava.SpellChecker"/>
</beans>
@Qualifier注解
当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier注解和@Autowire注解结合使用以消除这种混淆,指定需要装配的确切的bean。
例如,这里我们分别有两个类,Employee和EmpAccount。在EmpAccount中,使用@Qualifier指定了必须装配id为emp1的bean。
Employee.java
public class Employee {
private String name;
@Autowired
public void setName(String name) {
this.name = name;
}
public string getName() {
return name;
}
}
EmpAccount.java
public class EmpAccount {
private Employee emp;
@Autowired
@Qualifier(emp1)
public void showName() {
System.out.println(“Employee name: ”+emp.getName);
}
}
@Qualifier注解意味着可以在被标注bean的字段上可以自动装配。Qualifier注解可以用来取消Spring不能取消的bean应用。
下面的示例将会在Customer的person属性中自动装配person的值。
public class Customer{
@Autowired
private Person person;
}
下面我们要在配置文件中来配置Person类。
<bean id="customer" class="com.somnus.common.Customer"/>
<bean id="personA" class="com.somnus.common.Person">
<property name="name" value="lokesh"/>
</bean>
<bean id="personB" class="com.somnus.common.Person">
<property name="name" value="alex"/>
</bean>
Spring会知道要自动装配哪个person bean么?不会的,但是运行上面的示例时,会抛出下面的异常:
Caused by:org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type[com.howtodoinjava.common.Person]is defined:
expected single matching bean but found 2:[personA, personB]
要解决上面的问题,需要使用@Quanlifier注解来告诉Spring容器要装配哪个bean:
public class Customer{
@Autowired
@Qualifier("personA")
private Person person;
}
@Controller注解
该注解表明该类扮演控制器的角色,Spring不需要你继承任何其他控制器基类或引用Servlet API。
@RequestMapping注解
@RequestMapping注解用于将特定HTTP请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:
类级别:映射请求的URL;方法级别:映射URL以及HTTP请求方法