标签:spring java spring mvc
Spring的自动装配与自动检测是为了最小化Spring XML配置,如果我们有很多的Bean要装配到spring 容器中,那么我们的配置文件将会看起来很长很长,让人觉得头晕,适当的使用自动装配与自动检测,将有助于缓解以上提到的问题
*自动装配:(autowiring) 有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系。
*自动检测:(autodiscovery) 比自动装配更进一步,让Spring能够自动识别哪些类需要被装配成SpringBean 从而减少对<bean> 元素的使用
自动装配
spring提供了四种自动装配的方式
* byName 把Bean的属性具有相同名字的的其他Bean自动装配到Bean的对应属性中
* byType 把与Bean的属性具有相同类型的的其他Bean 自动装配Bean的对应属性当中
* constructor 把与Bean 的构造器入参具有相同类型的其他Bean自动装配到构造器的对应入参中
*autodetect 首先尝试使用constructor进行自动装配,如果失败,再使用byType进行自动装配
byName
<bean id="kenny2" class="xxx.xxx.xxx"> <property name="song" value="Jingle Bells"/> <property name="instrument" ref="saxophone"/> </bean> <!--以下是使用自动装配,假设这里定义的id为instrument--> <bean id="instrument" class="xxx.xxx.xxx"/> <bean id="kenny" class="xxx.xxx.xxx" autowire="byName"> <property name="song" value="Jingle Bells"/> </bean>
byType
<bean id="kenny" class="xxx.xxx.xxx" autowire="byType"> <property name="song" value="Jingle Bells"/> </bean>
只需要把autowire属性值改为byType就可以了,但是在应用上下文当中,如果有多个bean的类型与该bean的自动装配属性相匹配,那么就会出错,因为byType方式只允许匹配一个类型相同的Bean,如果应用上下文存在多个类型相同的bean怎么办呢,spring提供了另外两种选择,可以设置一个首选bean,或者排除一些bean。
<bean>元素的primary属性代表是否是首选bean,如果标注为true,那么该bean将成为首选bean,但是spring默认每个bean的primary属性都市true,所以如果需要设置首选bean需要将那些非首选bean的primary属性标注为false。
如果我们在自动装配的过程当中,想排除某些bean的时候,可是使用把autowire-candidate属性设置为false。
看如下代码
<bean id="kenny" class="xxx.xxx.xxx" autowire="byType" primary="false"> <property name="song" value="Jingle Bells"/> </bean><pre name="code" class="html"><bean id="kenny" class="xxx.xxx.xxx" autowire="byType" autowire-candidate="false"> <property name="song" value="Jingle Bells"/> </bean>
如上两个例子分别代表了以上描述的两种选择
constructor
<bean id="kenny" class="xxx.xxx.xxx" autowire="constructor"> <property name="song" value="Jingle Bells"/> </bean>构造器自动装配只需要把autowire属性设置为constructor就可以了,这样就免去了声明<constructor-arg>元素
最佳自动装配(autodetect)
<bean id="kenny" class="xxx.xxx.xxx" autowire="autodetect"> <property name="song" value="Jingle Bells"/> </bean>首先使用constructor如果失败,就是使用byType,使用方法跟以上介绍的都是一样的 ,这里不多说了
默认自动装配
如果在一个配置文件中,所有的装配都使用同一种自动配置方式的话, 要在每个bean声明的时候都加上一个autowire属性也是很麻烦的,为了避免这样的重复操作,可以使用默认自动装配。
使用默认自动装配的方法是在<beans>元素中添加一个default-autowire属性,添加了这个属性之后,该配置文件当中的自动装配方式将以默认的方式来装配,如果有某个个别的bean需要使用其他的方式,在该bean上直接设置autowire属性就可以了,会覆盖掉默认自动装配的配置,代码如下。
<beans ... default-autowire="byType"> </beans>
使用注解装配
在使用注解装配之前,首先要开启注解装配的方式,那就是在配置文件中加上下面这句话
<context:annotation-config>
spring支持多种注解装配的方式,这里主要介绍spring自带的注解装配
使用@Autowired注解
该注解几乎可以用在任何方法上,只要该方法需要自动装配参数都可以,不一定非得是setter方法,但是一般都是使用在setter方法和构造器上的,看如下代码
@Autowired public void setInstrument(Instrument instrument){ this.instrument = instrument; }以上代码是把@Autowired注解放在setter方法上,在spring创建该类的bean的时候,就会自动寻找匹配的参数注入到该bean当中,当但参数需要同时在应用上下文中装配才可以,不然的话是找不到的。
@Autowired另外一个用法就是注解构造函数
@Autowired public Instrumentalist(Instrument instrument){ this.instrument = instrument; }
@Autowired private Instrument instrument;
注意:@Autowired使用的时候必须只有一个Bean适合装配到@Autowired注解所标注的属性或者参数中,否则的话,spring会抛出异常,如果在应用上下文当中找不到相应的bean去自动装配,那么spring也会抛出异常(NoSuchBeanDefinitionException),如果想避免这种情况发生,而且需要装配的属性也不是必须要装配的话,可以使用如下代码来使用注解
@Autowired(required=false) private Instrument instrument;在这里添加@Autowired的required属性,将这个属性设置为false,意思就是在创建bean的时候该属性不是必须的
@Qualifier注解
如果在同一个应用上下文当中出现了两个都必须存在的bean,然而自动装配只需要装配期中一个,这个时候可以使用@Qualifier注解指定一个Bean来装配,这样就不会报异常了
@Autowired @Qualifier("guitar") private Instrument instrument;括号中的字符串标注的是需要自动装配进来的Bean的id
在使用注解自动装配的过程当中,如果想要自动装配基本类型的或者是字面值常量的参数的话,可以是用@Value注解
@Value("Eruption") private String song;在这里自动装配为一个String类型的属性装配了一个String类型的值,同样可以装配int,boolean等基本类型的属性。
在@Value注解中,我们可以使用表达式来动态的计算并装配属性的值比如使用spel表达式从系统属性中取得一个值
@Value("#{systemProperties.myFavoriteSong}") private String song;
自动检测Bean
自动检测可以让Spring从指定的保重自动扫描需要被装配到容器当中的bean,但是在使用之前,需要先开启自动装配,这就需要在spring的配置文件当中配置如下的代码
<context:component-scan base-package="com.springinaction.springidol"></context:component-scan>在这个配置下spring会自动检测com.springinaction.springidol保重的所有可以被注册为springbean的类,然后自动生成相应的bean。
可以使用如下注解来标识哪些类是可以自动注册为Springbean的类
* @Component 通用的构造型注解,标识该类为spring组件
* @Controller 标识将该类定义为spring MVC 控制器
* @Repository 标识将该类定义为数据仓库(在使用数据库的时候可以用到该注解)
* @Service 标识将该类定义为服务
* 使用@Component标注的任意自定义注解
@Component public class Guitar implements Instrument{ public void play(){ System.out.println("......"); } }在该场景下GuitarBean的id将被设置为默认的guitar
可以在@Component注解中指定Bean的id
@Component("eddie") public class Guitar implements Instrument{ public void play(){ System.out.println("......"); } }这样在spring容器中该类的Bean的id就变为了eddie
spring的自动检测还包含了一种不实用注解的自动检测规则,该规则在今后程序中用到的时候再来介绍,这里不过多介绍了
Spring实战笔记4---Spring的自定装配与自动检测
标签:spring java spring mvc
原文地址:http://blog.csdn.net/u011374590/article/details/38831105