Spring中Bean的自动装配之@Autowired

Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;
 * 
@Autowired:自动注入:
 *         1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
 *         2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
 *                             applicationContext.getBean("bookDao")
 *         3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
 *         4)、自动装配默认一定要将属性赋值好,没有就会报错;
 *             可以使用@Autowired(required=false);
 *         5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
 *                 也可以继续使用@Qualifier指定需要装配的bean的名字
 *         BookService{
 *             @Autowired
 *             BookDao  bookDao;
 *         }

@Autowired标注位置:可放在构造器,参数,方法,属性上;且都是从容器中获取参数组件的值
 *         1)、【标注在方法位置即set方法上】标注在方法上,Spring容器创建当前对象,就会调用方法,完成赋值;方法使用的参数,自定义类型的值从ioc容器中获取
如:    @Autowired
              public void setCar(Car car) {
             this.car = car;
          }

 *         2)、【标在构造器上】:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取;构造器要用的组件,都是从容器中获取

如:    @Autowired(如果组件只有一个有参构造器,可省略)
           public Boss( Car car){
               this.car = car;
              System.out.println("Boss...有参构造器");
          }

 *         3)、【放在参数位置】:

@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的,也可以从容器中获得对象,完成自动装配。

如:    @Bean
           public Color color(@Autowired Car car){} (可省略)

如:    public void setCar(@Autowired Car car) {
             this.car = car;
          }

如:   public Boss(@Autowired Car car){  (如果组件只有一个有参构造器,可省略)
               this.car = car;
              System.out.println("Boss...有参构造器");
          }


情景一、只有一个bean实例时,看自动注入获取的bean和spring上下文获取的bean是不是一个

1、定义BookDao.java

package com.atguigu.dao;

import org.springframework.stereotype.Repository;

//名字默认是类名首字母小写
@Repository
public class BookDao {


}

2、定义BookService.java

用@Autowired自动装配bookDao

package com.atguigu.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.atguigu.dao.BookDao;


@Service
public class BookService {

    @Autowired
	private BookDao bookDao;
	
	public void print(){
		System.out.println(bookDao);
	}

	@Override
	public String toString() {
		return "BookService [bookDao=" + bookDao + "]";
	}	
}

3、定义BookController.java 

package com.atguigu.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.atguigu.service.BookService;

@Controller
public class BookController {
	
	@Autowired
	private BookService bookService;

}

4、定义配置类

package com.atguigu.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;


@Configuration
@ComponentScan({"com.atguigu.service","com.atguigu.dao",
	"com.atguigu.controller","com.atguigu.bean"})
public class MainConifgOfAutowired {
	
}

5、测试

看是否通过service中获取的dao和spring容器获取的dao是一个对象

package com.atguigu.test;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.atguigu.config.MainConifgOfAutowired;
import com.atguigu.dao.BookDao;
import com.atguigu.service.BookService;

public class IOCTest_Autowired {
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConifgOfAutowired.class);
		
		BookService bookService = applicationContext.getBean(BookService.class);
		System.out.println(bookService);
		
		BookDao bean = applicationContext.getBean(BookDao.class);
		System.out.println(bean);
		
	}

}

测试结果:

Spring中Bean的自动装配之@Autowired_第1张图片

说明:通过service中获取的dao和spring容器获取的dao是一个对象

 情景二、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找

 1、定义BookDao.java,默认lable的值为1

package com.atguigu.dao;

import org.springframework.stereotype.Repository;

//名字默认是类名首字母小写
@Repository
public class BookDao {
	
	private String lable = "1";

	public String getLable() {
		return lable;
	}

	public void setLable(String lable) {
		this.lable = lable;
	}

	@Override
	public String toString() {
		return "BookDao [lable=" + lable + "]";
	}

}

2、 定义BookService.java

package com.atguigu.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.atguigu.dao.BookDao;


@Service
public class BookService {
	
    @Autowired
	private BookDao bookDao;
	
	public void print(){
		System.out.println(bookDao);
	}

	@Override
	public String toString() {
		return "BookService [bookDao=" + bookDao + "]";
	}

}

3、定义配置类

自己new一个bean,并设置lable值为2

package com.atguigu.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.atguigu.dao.BookDao;

@Configuration
@ComponentScan({"com.atguigu.service","com.atguigu.dao",
	"com.atguigu.controller","com.atguigu.bean"})
public class MainConifgOfAutowired {
	
	@Primary
	@Bean("bookDao2")
	public BookDao bookDao(){
		BookDao bookDao = new BookDao();
		bookDao.setLable("2");
		return bookDao;
	}

}

4、测试获得的对象是哪个

package com.atguigu.test;

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.atguigu.config.MainConifgOfAutowired;
import com.atguigu.dao.BookDao;
import com.atguigu.service.BookService;

public class IOCTest_Autowired {
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConifgOfAutowired.class);
		
		BookService bookService = applicationContext.getBean(BookService.class);
		System.out.println(bookService);		
		
	}

}

结果:

说明:默认按照service中引用dao的属性名去查找,即:private BookDao bookDao;中的bookDao;

情景三、使用@Qualifier指定需要装配的组件的id,而不是使用属性名 

1、修改BookService.java类

添加@Qualifier("bookDao2"),指定使用id=bookDao2

package com.atguigu.service;


import javax.annotation.Resource;
import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.atguigu.dao.BookDao;


@Service
public class BookService {
	
	@Qualifier("bookDao2")
	@Autowired
	@Inject
	private BookDao bookDao;
	
	public void print(){
		System.out.println(bookDao);
	}

	@Override
	public String toString() {
		return "BookService [bookDao=" + bookDao + "]";
	}	

}

执行test01测试:

结果:

说明:会根据@Qualifier("bookDao2")指定的id去使用

情景四、加载的bean属性没有实现类

使用@Autowired(required=false),这样程序就不会报错

修改BookService .java

package com.atguigu.service;


import javax.annotation.Resource;
import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.atguigu.dao.BookDao;


@Service
public class BookService {
	
	@Qualifier("bookDao2")
	@Autowired(required=false)
	@Inject
	private BookDao bookDao;
	
	public void print(){
		System.out.println(bookDao);
	}

	@Override
	public String toString() {
		return "BookService [bookDao=" + bookDao + "]";
	}

}

情景五、设置默认使用首选的bean

注册bean时上添加@Primary注解:让Spring进行自动装配的时候,默认使用首选的bean;
修改配置类MainConifgOfAutowired.java,添加@Primary注解,表示默认使用此bean,则不会再根据属性去找bean

@Configuration
@ComponentScan({"com.atguigu.service","com.atguigu.dao",
	"com.atguigu.controller","com.atguigu.bean"})
public class MainConifgOfAutowired {
	
	@Primary
	@Bean("bookDao2")
	public BookDao bookDao(){
		BookDao bookDao = new BookDao();
		bookDao.setLable("2");
		return bookDao;
	}	

}

当然,也可以继续使用@Qualifier指定需要装配的bean的名字,@Primary就不会再起作用。

你可能感兴趣的:(spring,spring自动装配)