自动装配就是Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值,也就是根据指定的装配规则(可以是属性名,也可以是属性类型),Spring会自动将匹配的属性值在IOC容器中进行注入。
autowire
属性,可用来完成自动装配,这样就可以完成基于xml方式的自动装配。 * autowire属性值:
* byName:根据属性名称注入,但注入值bean的id需要和类属性名一致
* byType:根据属性类型注入,但不能声明多个同类型注入值bean
property
标签的ref
属性进行bean引用,或者在property标签中进行bean注入
,而自动装配则使用的是bean标签中的autowired属性
,如下举例public class Dept {
private String deptName;
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptName() {
return deptName;
}
@Override
public String toString() {
return "Dept{" +
"deptName='" + deptName + '\'' +
'}';
}
}
##########################################
public class Emp {
private Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
@Override
public String toString() {
return "Emp{" +
"dept=" + dept +
'}';
}
public void test(){
System.out.println(dept);
}
}
##################################3333
Spring配置文件
<bean id="emp" class="com.spring5.autowire.Emp" autowire="byName"></bean>
<bean id="dept" class="com.spring5.autowire.Dept">
<property name="deptName" value="实验部"/>
</bean>
##################################3333
测试代码
@Test
public void testAutoWire(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean8.xml");
com.spring5.autowire.Emp emp = context.getBean("emp", com.spring5.autowire.Emp.class);
System.out.println(emp);
}
@Autowired 可以标注在方法和构造器,参数,属性位置,但都是从IOC容器中获取参数组件的值:
* 方法上:
Spring 容器创建当前对象时,就会调用被标注的方法完成赋值
方法所需的参数若是自定义类型,则从IOC容器中获取
使用@Bean+方法参数,参数从容器中获取,默认不写@Autowired
* 构造器:
默认加在IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
构造器要用的组件,也都是从容器中获取,(当前类(组件)若只有一个有参构造器,@Autowired可省略)
* 参数:
同从容器中获取
相关代码
//@Component
public class Car {
public Car() {
System.out.println("Car constructor");
}
}
#########################
@Component
public class Boss {
private Car car;
public Boss(Car car) {
System.out.println("Boss args contrastor");
this.car = car;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
}
@Autowired
public void setCar(Car car) {
this.car = car;
}
@Autowired
public Boss(Car car) {
System.out.println("Boss args contrastor");
this.car = car;
}
public Boss(String name, Car car) {
this.name = name;
this.car = car;
}
public void setCar(@Autowired Car car) {
this.car = car;
}
1。一个组件需要调用另外一个组件,只需要在被调用的组件上标注@Autowired即可;
默认优先按照类型去容器中找对应的组件,找到就赋值;
2。如果找到多个相同类型的组件,再将属性名作为组件id去容器中查找,也就是在容器中找到了多个类型相同的组件,但组件id肯定不会相同,这个时候就看添加@Autowired注解的属性名是什么 ,优先选择组件ID和属性名一致的组件进行注入(也可以通过修改属性名来选择组件)
3。@Qualifier :指定需要装配的组件的id,而不是使用属性名;就是容器中有多个同类型组件,但是会默认优先选择组件ID同属性名的组件,而此时我们又只想要另一个与属性名不同名的组件,此时,就可以使用@Qualifier注解进行组件指定
4。自动装配默认一定要先对属性进行赋值,可在容器中找到该组件,否则会报错 ,也就是说我们在进行自动装配时,一定要先将组件注入到IOC容器中,使用@Autowired就相当于对属性赋值,而这个赋值就是是在容器中找到对应的组件,将该组件与属性进行绑定,完成属性赋值操作;如果说我们没有在IOC容器中进行组件注册,就需要使用@Autowired(required = false)进行设置,required默认true,就是必须要在容器中注册之后才能进行赋值操作,设置为false之后就是能在容器中找到就进行装配,找不到就不管了,组件赋值为null
5。@Primary:让Spring在进行自动装配时,默认首选注册的bean,也就是容器中有多个同类型组件时,默认优先选择标识@Primary注解的组件,所以该注解与@Qualifier相矛盾,前者是默认优先选择,后者是明确指定,如果同时添加@Qualifier注解,则就继续装配指定的组件了
(当我们按类型在容器中获取某单个bean实例时,如果出现多个同类型bean时会报错,但如果某个组件使用@Primary注解时就会选择@primary注解的bean,如果需要其他组件,此时就需要按照组件名字去容器中获取)
controller调用service,service调用dao
@Controller
public class BookController {
@Autowired
private BookService bookService;
public BookService getBookService() {
return bookService;
}
}
#####################################
测试代码
@Test
public void test3() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyconfigOfAutoWired.class);
BookController bean = context.getBean(BookController.class);
System.out.println(bean.getBookService());
}
###################################
两个dao组件
@Repository
public class BookDao {
private String label = "1"; // 识别组件标签
}
@Bean("bookDao2")
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLabel("2");
return bookDao;
}
###################################
service
@Service
public class BookService {
@Autowired
private BookDao bookDao;
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
#####################################
测试代码
@Test
public void test4() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyconfigOfAutoWired.class);
BookService bean = context.getBean(BookService.class);
System.out.println(bean);
}
@Service
public class BookService {
@Autowired
@Qualifier("bookDao2")
private BookDao bookDao;
}
其余代码同上2.1.1.2 ,只需添加 @Qualifier("bookDao2")
@Service
public class BookService {
@Autowired
private BookDao bookDao;
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
@Service
public class BookService {
@Autowired(required = false)
private BookDao bookDao;
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
@Bean("bookDao2")
@Primary
public BookDao bookDao(){
BookDao bookDao = new BookDao();
bookDao.setLabel("2");
return bookDao;
}
********************************************
@Service
public class BookService {
@Autowired
// @Qualifier("bookDao")
private BookDao bookDao;
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
################################################
测试代码
@Test
public void test4() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyconfigOfAutoWired.class);
BookService bean = context.getBean(BookService.class);
System.out.println(bean);
}
运行结果:
去掉@Qualifier(“bookDao”)注释之后运行结果:
@Resource
:
可以和@Autowired一样实现自动装配功能,
默认按照组件名称进行装配,
但不支持@Primary和@Autowired(required=false) 功能
@Inject
:
功能等同@Autowired,
但无@Autowired(required=false) 功能