自动装配:Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系的赋值。
新建controller,service,dao包,在各个包下,分别新建BookController,BookService,BookRepository类。
package com.ljessie.controller;
import com.ljessie.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class BookController {
@Autowired
private BookService bookService;
}
package com.ljessie.service;
import com.ljessie.dao.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.inject.Inject;
@Service
public class BookService {
@Autowired
private BookRepository bookRepository;
public void print(){
System.out.println(bookRepository);
}
@Override
public String toString() {
return "BookService{" +
"bookRepository=" + bookRepository +
'}';
}
}
package com.ljessie.dao;
import org.springframework.stereotype.Repository;
//名字是默认的首字母小写
@Repository
public class BookRepository {
private String lable = "1";
public String getLable() {
return lable;
}
public void setLable(String lable) {
this.lable = lable;
}
@Override
public String toString() {
return "BookRepository{" +
"lable='" + lable + '\'' +
'}';
}
}
新建MainConfigOfAutowired类
package com.ljessie.config;
import com.ljessie.bean.Car;
import com.ljessie.bean.Color;
import com.ljessie.dao.BookRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
@ComponentScan({"com.ljessie.service","com.ljessie.controller","com.ljessie.dao"})
public class MainConfigOfAutowired {
}
新建IOCTest_Autowired
package com.ljessie.test;
import com.ljessie.bean.Boss;
import com.ljessie.bean.Car;
import com.ljessie.bean.Color;
import com.ljessie.config.MainConfigOfAutowired;
import com.ljessie.config.MainConfigOfLifeCycle;
import com.ljessie.dao.BookRepository;
import com.ljessie.service.BookService;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class IOCTest_Autowired {
@Test
public void test01(){
//创建IOC容器
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
System.out.println("容器创建完成");
BookService bean = annotationConfigApplicationContext.getBean(BookService.class);
BookRepository bean1 = annotationConfigApplicationContext.getBean(BookRepository.class);
System.out.println(bean1.toString());
System.out.println(bean.toString());
System.out.println(annotationConfigApplicationContext);
//关闭容器
annotationConfigApplicationContext.close();
}
}
运行test01()
容器创建完成
BookRepository{lable='1'}
BookService{bookRepository=BookRepository{lable='1'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 10:52:38 CST 2020]; root of context hierarchy
一月 19, 2020 10:52:38 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 10:52:38 CST 2020]; root of context hierarchy
Autowired自动注入:
1.默认优先按照类型去容器中找对应的组件,annotationConfigApplicationContext.getBean(BookRepository.class);如果找到,就赋值。
2.如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找annotationConfigApplicationContext.getBean("bookRepository")
@Qualifier("bookRepository"):使用@Qualifier指定需要装配组件的id,而不是使用属性。
在MainConfigOfAutowired添加方法
@Bean("bookRepository2")
public BookRepository bookRepository(){
BookRepository bookRepository = new BookRepository();
bookRepository.setLable("2");
return bookRepository;
}
在BookService里面,给bookRepository添加@Qualifier注解,指定装配bookRepository
@Qualifier("bookRepository")
@Autowired(required = false)
private BookRepository bookRepository;
注掉test01()获取bookRepository组件代码,否则会报错
//BookRepository bean1 = annotationConfigApplicationContext.getBean(BookRepository.class);
//System.out.println(bean1.toString());
运行test01()
容器创建完成
BookService{bookRepository=BookRepository{lable='1'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:00:14 CST 2020]; root of context hierarchy
一月 19, 2020 11:00:15 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:00:14 CST 2020]; root of context hierarchy
给BookService里面注入的BookRepository的id为bookRepository。修改@Qualifier为@Qualifier("bookRepository2")
@Qualifier("bookRepository2")
@Autowired(required = false)
private BookRepository bookRepository;
再运行test01(),给BookService里面注入的BookRepository为MainConfigOfAutowired里面bookRepository()方法配置的BookRepository。
容器创建完成
BookService{bookRepository=BookRepository{lable='2'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:02:32 CST 2020]; root of context hierarchy
一月 19, 2020 11:02:32 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:02:32 CST 2020]; root of context hierarchy
@Primary:让Spring进行自动装配的时候,默认使用首选的Bean。也可以继续使用@Qualifier指定需要装配的bean的名字。
注掉BookService里面的@Qualifier注解
//@Qualifier("bookRepository2")
@Autowired(required = false)
private BookRepository bookRepository;
MainConfigOfAutowired类的bookRepository()方法添加@Primary注解
@Primary
@Bean("bookRepository2")
public BookRepository bookRepository(){
BookRepository bookRepository = new BookRepository();
bookRepository.setLable("2");
return bookRepository;
}
运行test01(),此时给BookService注入的BookRepository是bookRepository()方法配置的BookRepository。
容器创建完成
BookService{bookRepository=BookRepository{lable='2'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:07:09 CST 2020]; root of context hierarchy
一月 19, 2020 11:07:09 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:07:09 CST 2020]; root of context hierarchy
@Resource:Spring还支持使用@Resource(JSR250)注解,可以和Autowired一样进行自动装配,默认是按照组件名称进行装配。没有@Primary功能,也没有@Autowired(required=false)功能。
修改BookService代码
// @Qualifier("bookRepository2")
// @Autowired(required = false)
@Resource(name="bookRepository2")
private BookRepository bookRepository;
运行test01()
容器创建完成
BookService{bookRepository=BookRepository{lable='2'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:12:08 CST 2020]; root of context hierarchy
一月 19, 2020 11:12:08 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:12:08 CST 2020]; root of context hierarchy
@Inject:需要导入javax.inject包,和@Autowired功能一样,支持@Primary功能,没有@Autowired(required=false)
添加Maven依赖
<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
修改BookService代码
// @Qualifier("bookRepository2")
// @Autowired(required = false)
// @Resource(name="bookRepository2")
@Inject
private BookRepository bookRepository;
运行test01()
容器创建完成
BookService{bookRepository=BookRepository{lable='2'}}
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:15:24 CST 2020]; root of context hierarchy
一月 19, 2020 11:15:25 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 19 11:15:24 CST 2020]; root of context hierarchy
@Autowired是Spring定义的,@Resource和@Inject是JAVA规范。
@Autowired标注在方法上
新建Car
package com.ljessie.bean;
import org.springframework.stereotype.Component;
@Component
public class Car {
public Car(){
System.out.println("Car Constructor......");
}
public void init(){
System.out.println("Car init......");
}
public void destroy(){
System.out.println("Car destroy......");
}
}
新建Boss
package com.ljessie.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 默认加载IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值操作。
*/
@Component
public class Boss {
private Car car;
public Car getCar() {
return car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
/**
* 标注在方法上,Spring容器创建当前对象,就会调用此方法,完成赋值
* @param car 从IOC容器中获取
*/
// @Autowired
public void setCar(Car car) {
this.car = car;
}
}
在MainConfigOfAutowired类中,添加ComponentScan里面的数组,扫描bean包
@Configuration
@ComponentScan({"com.ljessie.service","com.ljessie.controller","com.ljessie.dao","com.ljessie.bean"})
public class MainConfigOfAutowired {
//省略其他代码
}
修改IOCTest_Autowired,test01()代码
@Test
public void test01(){
//创建IOC容器
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
System.out.println("容器创建完成");
// BookService bean = annotationConfigApplicationContext.getBean(BookService.class);
// BookRepository bean1 = annotationConfigApplicationContext.getBean(BookRepository.class);
// System.out.println(bean1.toString());
// System.out.println(bean.toString());
Boss boss = annotationConfigApplicationContext.getBean(Boss.class);
Car car = annotationConfigApplicationContext.getBean(Car.class);
System.out.println(boss);
System.out.println(car);
//
// Color color = annotationConfigApplicationContext.getBean(Color.class);
// System.out.println(color);
System.out.println(annotationConfigApplicationContext);
//关闭容器
annotationConfigApplicationContext.close();
}
运行test01()
Car Constructor......
容器创建完成
Boss{car=null}
com.ljessie.bean.Car@7ea37dbf
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:23:28 CST 2020]; root of context hierarchy
一月 26, 2020 2:23:28 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:23:28 CST 2020]; root of context hierarchy
在Boss中的setCar(Car car)方法上面,添加@Autowired注释
@Autowired
public void setCar(Car car) {
this.car = car;
}
再次运行test01():Boss中的Car属性已经被赋值
Car Constructor......
容器创建完成
Boss{car=com.ljessie.bean.Car@27c86f2d}
com.ljessie.bean.Car@27c86f2d
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:27:40 CST 2020]; root of context hierarchy
一月 26, 2020 2:27:40 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:27:40 CST 2020]; root of context hierarchy
@Autowired标注在构造器上:如果组件只有一个有参构造器,可以省略@Autowired,参数位置的组件还是从容器中获取。
在Boss中添加构造方法
/**
* 构造器要用的组件,也是从容器中获取
*/
@Autowired
public BossCar car){
this.car = car;
System.out.println("Boss....有参构造器");
}
运行test01():Spring调用Boss中的有参构造器,完成Car的赋值
Car Constructor......
Boss....有参构造器
容器创建完成
Boss{car=com.ljessie.bean.Car@6a01e23}
com.ljessie.bean.Car@6a01e23
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:30:05 CST 2020]; root of context hierarchy
@Autowired标注在参数上:修改Boss中的构造方法
/**
* 构造器要用的组件,也是从容器中获取
*/
// @Autowired
public Boss(@Autowired Car car){
this.car = car;
System.out.println("Boss....有参构造器");
}
运行test01():同样可以完成赋值操作。
Car Constructor......
Boss....有参构造器
容器创建完成
Boss{car=com.ljessie.bean.Car@1df82230}
com.ljessie.bean.Car@1df82230
org.springframework.context.annotation.AnnotationConfigApplicationContext@7a46a697: startup date [Sun Jan 26 14:33:46 CST 2020]; root of context hierarchy