Spring第八章:Spring自动注入
Posted reload
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring第八章:Spring自动注入相关的知识,希望对你有一定的参考价值。
一.自动注入
1.在 Spring 配置文件中对象名和 ref=”id”id 名相同使用自动注入,可以不配置<property/>
2.两种配置办法
2.1 在<bean>中通过 autowire=”” 配置,只对这个<bean>生效
2.2 在<beans>中通过 default-autowire=””配置,表当当前文件中所有<bean>都是全局配置内容
2.3 自动注入代码
2.3.1测试自动注入的实体类,老师和学生类
package com.suncl.model; import org.springframework.beans.factory.annotation.Value; /** * Created by SCL-PC on 2019/3/5. */ public class Teacher { private String name ="张三"; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Teacher{" + "name=‘" + name + ‘‘‘ + ‘}‘; } }
package com.suncl.model;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.Resource;
/**
* Created by SCL-PC on 2019/3/5.
*/
public class Student {
private String name = "李四";
private Teacher teacher22;
public Student(Teacher teacher22){
this.teacher22 = teacher22;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher22() {
return teacher22;
}
public void setTeacher22(Teacher teacher22) {
this.teacher22 = teacher22;
}
@Override
public String toString() {
return "Student{" +
"name=‘" + name + ‘‘‘ +
", teacher=" + teacher22 +
‘}‘;
}
}
2.3.2配置文件
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" >
<!--默认的注入方式 配置之后取beans的 default-autowire 如果默认的也没有配置就等同no-->
<bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>
<!--不自动注入-->
<bean id="student2" class="com.suncl.model.Student" autowire="no"></bean>
<!--按照名称自动注入 也就是id-->
<bean id="student3" class="com.suncl.model.Student" autowire="byName"></bean>
<!--按照类型自动注入 注意这里如果有两个相同的注入类型会报错-->
<bean id="student4" class="com.suncl.model.Student" autowire="byType"></bean>
<!--按照构造器自动注入-->
<bean id="student5" class="com.suncl.model.Student" autowire="constructor"></bean>
<bean id="teacher" class="com.suncl.model.Teacher"></bean>
<!--写来测试按照类型注入的时候出错的场景-->
<!--<bean id="teacher2" class="com.suncl.model.Teacher"></bean>-->
</beans>
2.3.3 测试类
package com.suncl.test; import com.suncl.model.Student; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by SCL-PC on 2019/2/28. */ public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student)ac.getBean("student3",Student.class); System.out.println(student.toString()); } }
3.autowire=”” 可取值
3.1 default: 默认值,根据全局 default-autowire=””值.默认全局和局部都没有配置情况下,相当于 no
<!--默认的注入方式 配置之后取beans的 default-autowire 如果默认的也没有配置就等同no--> <bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>
Student student = (Student)ac.getBean("student1",Student.class);
Student{name=‘李四‘, teacher=null}
运行结果可以看到 老师实体没有完成注入 但是我们如果配置了一个全局 default-autowire=””再看下结果
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName" > <!--默认的注入方式 配置之后取beans的 default-autowire 如果默认的也没有配置就等同no--> <bean id="student1" class="com.suncl.model.Student" autowire="default"></bean>
Student{name=‘李四‘, teacher=Teacher{name=‘张三‘}} 注入成功
3.2 no: 不自动注入
<!--不自动注入-->
<bean id="student2" class="com.suncl.model.Student" autowire="no"></bean>
Student student = (Student)ac.getBean("student2",Student.class); Student{name=‘李四‘, teacher=null}
不注入就只能是null了
3.3 byName: 通过名称自动注入.在 Spring 容器中找类的 Id
<bean id="student3" class="com.suncl.model.Student" autowire="byName"></bean>
Student student = (Student)ac.getBean("student3",Student.class);
Student{name=‘李四‘, teacher=Teacher{name=‘张三‘}}
可以看到按照名称注入了,怎么理解名称注入呢。假设我们现在修改下bean的id
<bean id="teacher22" class="com.suncl.model.Teacher"></bean> Student student = (Student)ac.getBean("student3",Student.class); Student{name=‘李四‘, teacher=null}
然后再执行测试类,发现无法注入成功。
然后我们再去修改学生类的属性,修改teacher属性为teacher22完成注入
private Teacher teacher22; public Teacher getTeacher22() { return teacher22; } public void setTeacher22(Teacher teacher22) { this.teacher22 = teacher22; }
Student student = (Student)ac.getBean("student3",Student.class); Student{name=‘李四‘, teacher=Teacher{name=‘张三‘}}
如下即可注入成功,所以byName的注入方式要求bean的id 和注入类的属性名称一致即可
3.4 byType: 根据类型注入.
<bean id="student4" class="com.suncl.model.Student" autowire="byType"></bean> Student student = (Student)ac.getBean("student4",Student.class); Student{name=‘李四‘, teacher=Teacher{name=‘张三‘}}
特别注意容器里面不可以出现两个相同类型的bean
<!--写来测试按照类型注入的时候出错的场景-->
<bean id="teacher2" class="com.suncl.model.Teacher"></bean>
例如我这边就定义了两个相同类型的Teacher实体。那么spring会出现错误
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.suncl.model.Teacher] is defined: expected single matching bean but found 2: teacher22,teacher2 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1288) ... 18 more
expected single matching bean but found 2: teacher22,teacher2。预期是一个满足的bean,但是找到了2个,立马就懵逼了。
3.5 constructor: 根据构造方法注入.
3.5.1 提供对应参数的构造方法(构造方法参数中包含注入对戏那个)
3.5.2 底层使用 byName, 构造方法参数名和其他<bean>的 id
public Student(Teacher teacher22){ this.teacher22 = teacher22; }
提供一个属性名称的构造器
<!--按照构造器自动注入--> <bean id="student5" class="com.suncl.model.Student" autowire="constructor"></bean> Student student = (Student)ac.getBean("student5",Student.class); Student{name=‘李四‘, teacher=Teacher{name=‘张三‘}}
注意:这里定义了属性名称构造器之后,spring会提示有上面的byName和byType会出现错误,需要再手动添加一个无参构造器。java默认会为所有的类提供无参构造器,
但是如果你自己写了任何有参数的构造器,那么默认的无参构造器就没有了。
以上是关于Spring第八章:Spring自动注入的主要内容,如果未能解决你的问题,请参考以下文章
SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-003-Pizza例子的基本流程
SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-001- 配置SpringFlow(flow-executorflow-registryFlowHand(代
第八章 分布式配置中心:Spring Cloud Config
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段