-
Bean的自动装配:让spring自动识别如何装配Bean的依赖关系
自动装配的四种策略:
类型 |
策略 |
举例 |
byName |
把与Bean属性具有相同名字的其他Bean自动装配到Bean的对应属性中,没有匹配的不装配 |
<bean id ="beanDemo" class="com.spring.demo.DemoBean" autowire="byName"> <property name="name" value="caka"/> </beans> |
byType |
把与Bean属性具有相同类型的其他Bean自动装配到Bean的对应属性中,没有匹配的不装配。spring提供两种装配设置,primary是true的优先装配,但该属性默认为true,所以设置了某个bean为优先装配时,需要将其他的bean的primary设置为false。若在自动装配时,希望排除某些bean,可以设置autowire-candidate为false |
<bean id ="beanDemo" class="com.spring.demo.DemoBean" primary="false"/>
<bean id ="beanDemo" class="com.spring.demo.DemoBean" autowire-candidate=“false”/>
|
constructor |
把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean的对应属性中,没有匹配的不装配。 |
<bean id ="beanDemo" class="com.spring.demo.DemoBean" autowire=“constructor”/> |
autodetect |
首先尝试constructor装配,如果失败,再使用byType装配 |
<bean id ="beanDemo" class="com.spring.demo.DemoBean" autowire=“autodetect”/> |
注意:使用constructor自动装配策略时,必须让spring自动装配构造器的所有入参,不能混合使用constructor自动装配策略和<constructor-arg>元素。
使用注解装配之spring自带注解@Autowired:
spring容器默认禁用注解装配的。我们需要在spring的配置在启动它才可以基于注解的自动装配。<context:annotation-config>元素表明使用基于注解的自动装配。
1.标注setter方法,使用注解就可以移除配置文件里对应的<property>元素了
@Autowired
public void setDemoBean(DemoBean demoBean){
this.demoBean=demoBean
}
2.标注构造器
@Autowired
public DemoAnnotation(DemoBean demoBean){
this.demoBean=demoBean
}
3.标注自动装配Bean引用的任意方法
@Autowired
public void otherMethod(DemoBean demoBean){
this.demoBean=demoBean
}
4.直接标注属性,并删除setter方法
@Autowired
private DemoBean demoBean;
关于@Autowired使用的注意点:
1.装配时没有匹配的Bean,会抛出NoSuchBeanDefinitionException异常,比如有时候属性不一定必须要装配,可以为null,设置@Autowired的required属性为false,装配时如果没有找到匹配的Bean会设为null。
@Autowired(required=false)
private DemoBean demoBean;
2.匹配到多个Bean时,使用@Qualifier注解装配指定Id的Bean。
@Autowired
@Qualifier(“demoId”)
private DemoBean demoBean;
3.构造器装配,只能有一个Bean的构造器可以将@Autowired的required属性设置为true,其他的需设置为false。
使用注解装配之@Inject:
@Inject与@Autowired一样,只是@Inject没有@required属性,因此@Inject标注的依赖关系必须存在,否则会抛出异常。
相对于@Autowired对应的@Qualifier,@Inject对应的是@Named
@Autowired
@Name(“demoId”)
private DemoBean demoBean;
-
Bean的自动检测:让spring能自动识别哪些类需要配置成Spring Bean,从而减少对<bean>元素的使用。配置spring的自动检测,需要使用<context:componenet-scan>元素。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=" http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:componenet-scan base-package="com.spring.demo"
</context:componenet-scan>
</beans>
<context:componenet-scan>元素会扫描指定的包及其子包,并查找出能自动注册为spring bean的类。但是问题来了:<context:componenet-scan>是如何确定哪些类需要注册为spring Bean呢?
基于注解的自动检测:
默认情况下,<context:componenet-scan>查找使用构造型注解所标注的类。
-
@Component:通用的构造器注解,标识该类为spring组件。
-
@Controller: 标识该类定义为SpringMVC的controller
-
@Repository:标识该类定义为数据仓库
-
@Service: 标识该类为服务类
可以通过平配置<context:componenet-scan>,并使用@Component注解标注DemoBean,来消除显示的<bean>定义。
package com.spring.demo;
import org.springframework.stereotype.Component;
@Component
//如果要指定bean的Id,可以在注解上直接指定如:@Component(“defaultBean”)
public class DemoBean{
//省略
}
spring扫描com.spring.demo包时,会发现使用@Component注解所标注的类DemoBean,并自动将它注册为Spring Bean。Bean的Id默认为无限定类名:demoBean,如果要指定bean的Id,可以在注解上直接指定如:@Component(“defaultBean”)。
组件扫描的自动检测:
通过为<context:componenet-scan>配置<context:include-filter>或者<context:exclude-filter>子元素,自动注册所有实现某spring bean接口的实现类。
<context:componenet-scan base-package="com.spring.demo"
<context:include-filter type="assignable" expression="com.spring.demo.Instrument">
<context:exclude-filter type="annotation" expression="com.spring.demo.skiptBean">
</context:componenet-scan>
<context:include-filter>的type和expression属性一起来协作定义组件扫描策略。所有派生于Instrument的所有类自动注册为spring Bean。而<context:exclude-filter>来告知spring哪些类不需要注册为Spring bean。