上篇文章主要讲了@Value的赋值:普通赋值,@Value("#{}"),spEl表达式赋值,@Value("&{}")读取配置文件赋值:
这篇文章主要介绍spring的自动装配,DI依赖注入,各个组件赋值,完成在IOC容器的组件调用。常用的@Autowird按类型去ioc容器中找组件注解,与之对应的有个@Resource按名称注解以后在讲解。
1、@Autowired
1)、默认优先[按照类型]去ioc容器中找组件 AnnotationConfigApplicationContext.getBean(BookDao.class);
2)、若此类型在容器中找到两个以上组件,则加载此方法找默认的名称AnnotationConfigApplicationContext.getBean("bookDao");
3)、可以和@Qualifier("组件名")组合使用,直接指定组件名。
4)、加载的@Autowired(required=false)必须在容器中存在此组件,IOC容器不存在则报错,默认为true,也可以指定为false,则不会报错。
5)、@Primary注解也可以指定主加载的组件,这时候就默认加载此主键的组件,除非@Qualifier指定其他组件。
/**
* @Autowired
* Spring 的自动装配:DI依赖注入,各个组件之间的装配赋值,完成对IOC容器里各个对象之间赋值调用。
* 1)、默认优先按照类型去ioc容器中找组件
*
* @author keying
* @Autowired
*/
@Configuration
@ComponentScan(value = {"com.alibaba.controller","com.alibaba.service","com.alibaba.dao"})
public class ConfigOfAutowired {
}
@Controller
public class BookController {
@Autowired
private BookService bookService;
public void print() {
System.out.println(bookService);
}
}
/**
* @author keying
* 加载进的ioc容器里的名字:默认首字母小写
*/
@Repository
public class BookDao {
}
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void print() {
System.out.println("BookService注入的bookDao:" + bookDao);
}
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
public class IOCTestAutowired {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
ConfigOfAutowired.class);
@Test
public void test1() {
//getBeanNames(applicationContext);
BookService bookService = applicationContext.getBean(BookService.class);
BookDao bookDao = applicationContext.getBean(BookDao.class);
System.out.println("bookService:" + bookService);
System.out.println("bookDao:" + bookDao);
applicationContext.close();
}
从junitTest打印的地址值可以看到,不管在bookService类取出的bookDao对象还是直接取的bookDao对象,指向java堆内存是同一个地址值。
2、@Qualifier
问:如果一个对象在ioc里创建两个组件,一个叫bookDao1,一个叫bookDao2,默认先加载哪个呢,如果指定加载哪个就可以用到@Qualifier("bookDao2")。代码如下:
@Service
public class BookService {
@Autowired
@Qualifier("bookDao2")
private BookDao bookDao;
public void print() {
System.out.println("BookService注入的bookDao:" + bookDao);
}
@Override
public String toString() {
return "BookService{" +
"bookDao=" + bookDao +
'}';
}
}
/**
* @author keying
* 加载进的ioc容器里的名字:默认首字母小写
*/
@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 + '\'' +
'}';
}
}
@Test
public void test1() {
//getBeanNames(applicationContext);
BookService bookService = applicationContext.getBean(BookService.class);
//BookDao bookDao = applicationContext.getBean(BookDao.class);
System.out.println("bookService:" + bookService);
//System.out.println("bookDao:" + bookDao);
applicationContext.close();
}
在Config配置文件里用@Bean注解新注册一个bookDao2组件,给BookDao类加一个lable字段,
1)、若加载的默认bookDao对象,则会打印lable为1
2)、若加载的bookDao对象,Autowird按类型加载,则需要用@Qualifier注解在BookService类指定加载的名称。