2.6 Annotation注解
基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。
上述程序我们可以替代如下:
UserDaoImpl类代码如下所示:
package impl; import org.springframework.stereotype.Repository; import dao.UserDao; @Repository("userDao") public class UserDaoImpl implements UserDao { @Override public void say() { System.out.println("helloworld spring!"); } } |
UserDaoImpl类代码中我们添加了注解@Repository("userDao")其功能相当于配置文件中的<bean id="userDao" class="impl.UserDaoImpl"></bean>代码。
UserServiceImpl类如代码下所示:
package impl;
import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import dao.UserDao; import dao.UserService; @Service("userService") public class UserServiceImpl implements UserService { @Resource(name="userDao") UserDao userDao; String username; List<String> list;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public List<String> getList() { return list; }
public void setList(List<String> list) { this.list = list; }
public UserDao getUserDao() { return userDao; }
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void show() { userDao.say(); System.out.println("userservice helloworld!"); System.out.println(username); System.out.println(list.get(0)); System.out.println(list.get(1)); } } |
UserServiceImpl类代码中我们添加了注解@Service("userService"),其功能相当于配置文件中的<bean id=" userService " class="impl. UserServiceImpl"></bean>代码。
而UserServiceImpl类代码中我们添加了注解@Resource(name="userDao"),其功能相当于配置文件中的<property name="userDao" ref="userDao"></property>代码。
最后程序运行结果与之前完全相同。这说明使用注解同样可以完成Bean的装配工作。
自动装配Bean属性
Spring提供了四种各具特色的自动装配策略:
1、byName-把与Bean的属性具有相同名字的其他Bean自动装配到Bean的对应属性中。如果没有跟属性的名字相匹配的Bean,则该属性不进行装配。
2、byType-把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。如果没有跟属性的类型相匹配的Bean,则该属性不被装配。
3、constructor-把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器的对应入参中。
4、autodetect-首先尝试使用constructor进行自动装配。如果失败,再尝试使用byType进行自动装配。
byName自动装配:
不使用byName自动装配之前是这样声明的:
<bean id="userService" class="impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> |
使用byName自动装配之后是这样的:
<bean id="userService" class="impl.UserServiceImpl" autowire="byName"> </bean> |
byName自动装配遵循一项约定,为属性自动装配ID与该属性的名字相同的Bean。通过设置autowire属性为byName,spring将为该bean的属性寻找与其名字相同的Spring Bean。使用byName的缺点是需要Bean的名字与其他bean的属性的名字一样。
byType自动装配:
byType自动装配的工作方式类似于byName自动装配,只不过不再是匹配属性的名字而是检查属性的类型。当我们尝试使用byType自动装配时,Spring会寻找哪一个Bean的类型与属性的类型相匹配。
constructor自动装配:
constructor自动装配具有和byType自动装配相同的局限性。当发现多个Bean匹配某个构造器的入参时,Spring不会尝试猜测哪一个Bean更适合自动装配。此外,如果一个类有多个构造器,它们都满足自动装配的条件时,Spring也不会尝试猜测哪一个构造器更适合使用。
最佳自动装配
如果想要自动装配bean,但是又不能决定该使用哪一种类型的自动装配,那么可以设置autowire属性为autodetect,由spring 来决定。
默认自动装配
如果需要为Spring应用上下文中的每一个bean(或者其中的大多数)配置相同的autowire属性,那么就可以要求Spring为它所创建的所有bean应用相同的自动装配策略来简化配置,所需要的做的仅仅是在根元素<beans>上添加一个default-autowire属性:
Spring应用上下文中的所有bean。可以在一个Spring应用上下文中定义多个配置文件,每一个配置文件都可以有自己的默认自动装配策略。同样的,不能因为配置了一个默认的自动装配策略,就意味着所有的bean都只能使用这个默认的自动装配策略,还可以使用<bean>元素的autowire属性来覆盖<bean>元素所配置的默认自动装配策略。

