上篇文章主要介绍了@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注解可以省略。