一、@value
javaBean
public class Bird {
//使用@Value进行赋值:1,基本字符 2,springEL表达式, 3,可以读取 我们的配置文件
@Value("James")
private String name;
@Value("#{20-2}")
private Integer age;
@Value("${bird.color}")
private String color;
public Bird() {
super();
}
public Bird(String name, Integer age, String color) {
super();
this.name = name;
this.age = age;
this.color = color;
}
//getter、setter 方法.......
}
config
@Configuration
//加载 properties 文件
@PropertySource("classpath:/test.properties")
public class Cap8MainConfig {
@Bean
public Bird bird(){
return new Bird();
}
}
properties
bird.color=red
test
public class Cap8Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfig.class);
Bird bird = (Bird) app.getBean("bird");
System.out.println(bird);
System.out.println("IOC容器创建完成........");
ConfigurableEnvironment environment = app.getEnvironment();
System.out.println("environment===="+environment.getProperty("bird.color"));
app.close();
}
}
输出
Bird [name=James, age=18, color=red]
IOC容器创建完成........
environment====red
注:@PropertySource(“classpath:/test.properties”) 会把properties 配置文件中的标量都扫进环境变量中,@Value("${bird.color}")去环境变量中取值
二、注解方式 声明 bean 与注入 bean
1.声明bean的注解
@Component 组件,没有明确的角色
@Service 在业务逻辑层使用(service层)
@Repository 在数据访问层使用(dao层)
@Controller 在展现层使用,控制器的声明(C)
注:以上注解纳入 springBean中,默认bean的Id是类名首字母小写,可选参数 value 可指定自定义 bean Id,如下:
如果是①,那么这个 service 的 bean Id 就是 TtetService
如果是②,那么 service 的 bean Id就是myTestService
//@Service(value = "myTestService") //②
@Service //①
public class TestService{
}
2、注入bean的注解
@Autowired:由Spring提供
@Inject:由JSR-330提供
@Resource:由JSR-250提供
都可以注解在set方法和属性上,推荐注解在属性上(一目了然,少写代码)。
@Autowired
1.@Autowired 是 spring 注解
2.@Autowired注解是按照类型(byType)装配依赖对象.
3.默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。
4.如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
5.可以设置属性@Autowired(required = false),表示如果没有接口的实现类,那么就注入 null
接口:
public interface ITestService {
void judgeService();
}
service 实现类1 TestService
@Service
public class TestService implements ITestService{
private TestDao testDao;
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 实现类2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller1
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired(required = true)
private TestService testService;
public void testSwichService(){
testService.judgeService();
}
}
controller2
@Controller
public class TestController {
@Autowired(required = true)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
controller3
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired(required = false)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
test
public class Cap9Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);
TestController testController = app.getBean(TestController.class);
testController.testSwichService();
}
}
说明:
1.如果执行的是 controller1,因为注入的 service 类型定是具体的实现类 TestService,所以@Autowired通过 byType 可以确定的 service 是TestService,所以输出的是『this is service2』
2.如果执行的是 contoller2,因为注入的是一个接口ITestService:
如果没有TestService2,ITestService的实现类就只有TestService,所以会正常的输出『this is service』
现在ITestService有两个实现类 TestService、TestService2,所以@Autowired就会不知道该注入哪个实现类,最后会报错:发现了两个实现类
3.如果执行的是 controller3,同样注入的是一个接口ITestService,因为有注解@Qualifier(“testService2”),代表指定ITestService接口实现类的 bean Id,且必须是实现了接口ITestService的 service,因为此时@Autowired(required = false),所以找不到的话iTestService会为 Null,不会报错
@Resource
1.jdk 自带注解,由JSR-250提供
2.默认按照 name(实际是 beanId)进行装配,如果name匹配不到才按 type进行匹配。需要注意的是,如果只按 name 匹配,如果 name 匹配不到,就不会按照类型就行匹配了,会报找不到。
3.必须有一个合适的实现类注入进来,不然会报错
接口
public interface ITestService {
void judgeService();
}
service 实现类1 TestService
@Service
public class TestService implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 实现类2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller
@Controller
public class TestController {
//所扫描的 bean 必须为ITestService的实现类
//查找 beanId 为 『testService』的 bean
@Resource(name = "testService")
//查找类型为『TestService.class』的 bean
@Resource(type = TestService.class)
//查找 beanId 为 『testService』且类型为『TestService.class』的 bean
@Resource(name = "testService",type = TestService.class)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
注:Resource 也可以使用 @Qualifier,但是 Resource 本身可以设置 name 属性,再使用@Qualifier多余,所以一般没人这样用的
@Qualifier、@Primary
@Qualifier(“xxxx”):帮助注解 byName
@Primary:用在声明注解,在注入接口,且接口有多个实现类,在无法唯一判断注入哪个具体的实现类时,注入标记了@Primary的实现类(只能有一个实现类加入这种标记)
接口
public interface ITestService {
void judgeService();
}
service 实现类1 TestService
@Primary
@Service
public class TestService implements ITestService{
private TestDao testDao;
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 实现类2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller1
@Controller
public class TestController {
@Autowired
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
controller2
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
test
public class Cap9Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);
TestController testController = app.getBean(TestController.class);
testController.testSwichService();
}
}
如果执行 controller1, controller未指明具体注入哪个实现类,所以 注入标记了@Primary 的 service,最后输出『this is service』
如果执行controller2,controller 使用@Qualifier(“testService2”),指明了注入的 beanId ,所以最终输出为『this is service2』
@Autowired和@Resource 的区别
相同点:
1.两个都是注入 bean 的注解
2.都支持@Qualifier、@Primary 注解(看过教程说 @Resource不支持@Primary,但是经过实验,是支持的)
不同点:
1.Autowired是 spring 的注解,Resource 是 jdk 的注解
2.Autowired有 require=false,如果找不到实现类就注入空。Resource 没有这种属性,找不到就报错
3.Autowired 只能默认通过 byType注入。Resource 可以通过 name、type 属性 来指定 byType、byName 注入。
特别的:在注入 bean 时,不管是 @Autowired、@Resource或是@Inject,都可以不靠@Qualifier、@Primary,或是@Resource的 name、type 属性来辅助注入唯一的实现类。只需要通过注入时的变量与 注册到 spring 容器中的 Bean Id 来对应即可,实际是利用 ByName 的属性:
接口:
public interface ITestService {
void judgeService();
}
service 实现类1 TestService
@Service
public class TestService implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 实现类2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller
@Controller
public class TestController {
@Autowired
// @Resource
// @Inject
//此处的变量名,需要与想要注入的实现类的 beanId 相同
private ITestService TestService2;
public void testSwichService(){
TestService2.judgeService();
}
}
最后输出结果:『this is service2』
未完,持续更新中。。。。。。