上篇文章主要介绍了@Resource和@inject:
1)这两个都是java的jre规范,之前的@Autowired是spring规范。
2)@Resource(name="")可以用name指定加载的组件名称,和@Autowired不同,@Autowired默认按类型加载,必须和@Qualifier一起才可以指定名字。
3)@Resource不可以和@Parimary连用,也不可以用@Autowired(required=false)。
4)@Inject必须导入mvn包,也不可以用@Autowired(required=false)。
有需要的同学可以点击链接查看:
Spring源码从入门到精通---@Resource&@Inject(十二)
这篇文章主要介绍构造器和方法的自动装配:
@Autowired可以修饰:构造器Construct,参数parameter,方法method,注解属性annotation_type,field。不管在哪修饰,都是从IOC容器中取。
1)放在方法上,可以放在set方法上测试(get不可以),常用的用法则是@Bean+方法参数,可以省略@Autowired,方法参数在IOC容器中获取组件。
2)标注在构造器上,若只有一个有参构造器,则可以省略@Autowired。
3)标注在参数上。
我们日常用常用的两个方法都是默认不写@Autowired的,但都是因为此注解,才获取到ioc容器中的bean。
一、在构造器中自动装配
写一个boss,boss里面定义一个之前写的car对象,注意car和boss都需要加上compoment注入容器,方便配置文件扫描。
/**
* @author keying
* 默认加载ioc容器中的组件,容器启动会调用无参构造器创建对象,在进行初始化赋值。
*/
@Component
public class Boss {
private Car car;
public Car getCar() {
return car;
}
//@Autowired
public Boss(@Autowired Car car) {
System.out.println("构造器用的组件:" + car);
this.car = car;
}
//@Autowired
public void setCar(Car car) {
System.out.println("方法上用的组件:" + car);
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
}
@Component
public class Car {
public Car(){
System.out.println("car ... construct");
}
private void init(){
System.out.println("car ... init");
}
private void destory(){
System.out.println("car ... destory");
}
}
复制
配置文件加上@ComponentScan注解加上新的扫描包:com.alibaba.bean
@Configuration
@ComponentScan(value = {"com.alibaba.controller", "com.alibaba.service", "com.alibaba.dao", "com.alibaba.bean"})
public class ConfigOfAutowired {
}
复制
写一个junitTest,获取Boss中的car,打印的看是否就是容器中的car。
@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);
System.out.println("=============从容器中获取Boss中的car========");
Boss boss = applicationContext.getBean(Boss.class);
System.out.println("boss:" + boss);
Car car = applicationContext.getBean(Car.class);
System.out.println("car:" + car);
applicationContext.close();
}
复制
从控制台打印结果可以看到,从boss中获取的car对象和IOC容器中是同一个对象@662ac478
二、在方法中自动装配
上面那个例子也可以看到从set方法中自动装配,这种因为很少见,所以就不仔细介绍,下面介绍bean注解注入对象,在方法上自动装配。
吧car类放入color类,并且这次color不用component注解注入容器,采用配置类里的@bean+传参方法。
public class Color {
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Color{" +
"car=" + car +
'}';
}
}
复制
@Configuration
@ComponentScan(value = {"com.alibaba.controller", "com.alibaba.service", "com.alibaba.dao", "com.alibaba.bean"})
public class ConfigOfAutowired {
/**
* 没选择Compoment注入,选择Bean注入,并且参数会直接从IOC容器中获取
*
* @return color
*/
@Bean
public Color color(Car car) {
Color color = new Color();
color.setCar(car);
return color;
}
}
复制
@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);
System.out.println("=============从容器中获取Boss中的car========");
Boss boss = applicationContext.getBean(Boss.class);
System.out.println("boss:" + boss);
Car car = applicationContext.getBean(Car.class);
System.out.println("car:" + car);
System.out.println("=============从Color中获取car");
Color color = applicationContext.getBean(Color.class);
System.out.println("color:" + color);
applicationContext.close();
}
复制
junitTest运行之后打印可以看到,所有地方获取的car都是ioc容器中的,并且@Autowired注解可以省略。