bean元素中autowire属性来设置自动注入的方式
<bean id="" class="X类" autowire=""/>
autowire有以下几个值
- byteName:按照名称进行注入 根据ID值和类名
- byType:按类型进行注入
- constructor:按照构造方法进行注入
- default:默认注入方式
default-autowire,beans标签的一个属性,可以配置默认注入方式,可选值(no|byName|byType|constructor|default)
bean元素中depend-on属性干预bean创建和销毁顺序
<bean id="bean1" class="" depend-on="bean2,bean3; bean4" />
depend-on:设置当前bean依赖的bean名称,可以指定多个,多个之间可以用逗号、分号、空格进行分割
上面配置规定,在创建bean1之前,必定先创建bean2、bean3、 bean4
销毁顺序是先销毁当前bean,再去销毁被依赖的bean
即先销毁bean1,再去销毁depend-on指定的bean。
bean的创建销毁顺序总结:
- 若没有定义depend-on属性也没有构造器注入规定强依赖,默认从按配置文件从上到下创建,销毁相反,类似栈,后进先出。
- 若通过构造器注入,bean3依赖于bean2,bean2依赖于bean1,创建顺序为123,销毁顺序为321
3.depend-on规定了依赖,先创建depend-on规定的依赖,在创建bean。销毁时先销毁bean再销毁依赖。
spring注入常见异常
org.springframework.beans.factory.NoUniqueBeanDefinitionException
当要进行注入时,有多个bean符合要求,而spring不知道该注入哪个bean
bean的primary属性:当有多个bean符合要求,spring不知道该注入哪个时,可以此属性规定默认注入的bean。主要候选者。默认值为false,值为false\true\default
bean的autowire-candidate属性 可以设置某个bean是否在自动注入的时候是否为作为候选
bean。仅自动注入时生效。默认值是true默认都是生效的
在自动注入时,当spring检测到有多个候选bean时,先检查autowire-candidate是否 为true,再检查primary属性是否为true。2层筛选后在进行注入,如果仍有多个bean则报异常。
另外beans中有属性default-autowire-candidates值为通配符。默认值null。例如
default-autowire-candidates="*Service"
beans元素的default-autowire-candidates和bean元素的autowire-candidate来决定最终
bean元素。如何决定的下面从源码分析。
spring源码:
//获取bean元素的autowire-candidate值
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
//判断bean元素的autowire-candidate值是否为default
if (isDefaultValue(autowireCandidate)) {
//值是default
//获取beans的default-autowire-candidates值
String candidatePattern = this.defaults.getAutowireCandidates();
//default-autowire-candidates是否为null
if (candidatePattern != null) {
//不为null
//判断bean的名称是否和default-autowire-candidates的值匹配
String[] patterns =
StringUtils.commaDelimitedListToStringArray(candidatePattern);
//匹配设为true,否则设为false
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns,
beanName));
}
}else {
//autowire-candidate值不为defalut
//设置规定的值true或者false
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
源码的位置是
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefi
nitionAttributes
bean初始化的2种方式(lazy-init懒加载)
实时初始化
随容器启动自动组装好的bean这些bean默认单例
延迟初始化
在容器启动过程中不会创建,而是使用的时候才会去创建
什么时候被使用
- 被其他bean作为依赖进行注入的时候。
- 自己写代码向容器中查找bean的时候,如getBean方法。
bean的lazy-init 属性配置bean是否是延迟加载,true:延迟初始化,false:实时
初始化(懒加载)
缺点:
延迟初始化的bean无法在程序启动过程中迅速发现bean定义的问题
第一次获取的时候耗时比较长。
parent继承
可以对比抽象类,子类父类的关系去理解。
abstract设置是否抽象bean。
抽象bean不会被创建
parent属性指定父bean
<bean id="baseService" abstract="true">
<property name="name" value="小明"/>
<property name="age" ref="20"/>
</bean>
<bean id="service1" class="com.zzb.test" parent="baseService"/>
<bean id="service2" class="com.zzb.test" parent="baseService"/>
子bean可以覆盖父bean属性配置
<bean id="service3" class="com.zzb.test" parent="baseService">
<property name="name" value="小王"/>
<property name="address" value="北京"/>
</bean>
bean标签内的标签lookup-method和replaced-method
lookup-method 方法查找,方法拦截
<bean id="class1" class="com.zzb.Class1">
<bean id="class2" class="com.zzb.Class2">
<lookup-method name="getClass1" bean="class1"/>
</bean>
作用:在调用getClass1方法的时候,拦截代码中写的方法,执行配置文件中内容,原方法返回null的话,这里返回的是class1的实例
replaced-method方法替换
提供替换方法的类要实现MethodReplacer和ApplicationContextAware接口,同时要注册到spring容器中
public class getclass1MethodReplacer implements MethodReplacer,ApplicationContextAware {
@Override
public Object reimplement(Object obj, Method method, Object[] args) throws
Throwable {
return this.context.getBean(Class1.class);
}
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
}
<bean id="MethodReplacer" class="com.zzb.getclass1MethodReplacer"></bean>
<bean id="class2" class="com.zzb.Class2">
<replaced-method name="getClass1" replacer="Methodreplacer"/>
</bean>