Spring系列第21篇:注解实现依赖注入(@Autowired、@Resource、@Primary、(1)

boolean required() default true;

}

可以用在构造器、方法、方法参数、字段、注解上。

参数:

required:标注的对象是否必须注入,可能这个对象在容器中不存在,如果为true的时候,找不到匹配的候选者就会报错,为false的时候,找不到也没关系 。

@Autowire查找候选者的过程

查找过程有点复杂,看不懂的可以先跳过,先看后面案例,本文看完之后,可以回头再来看这个过程。

@Autowired标注在字段上面:假定字段类型为一个自定义的普通的类型,候选者查找过程如下

@Autowired标注在方法上或者方法参数上面:假定参数类型为为一个自定义的普通的类型,候选者查找过程如下:

上图中深色的表示方法注入和字段注入查找过程的不同点。

上图中展示的是方法中只有一个参数的情况,如果有多个参数,就重复上面的过程,直到找到所有需要注入的参数。

将指定类型的所有bean注入到Collection中

如果被注入的对象是Collection类型的,可以指定泛型的类型,然后会按照上面的方式查找所有满足泛型类型所有的bean

将指定类型的所有bean注入到Map中

如果被注入的对象是Map类型的,可以指定泛型的类型,key通常为String类型,value为需要查找的bean的类型,然后会按照上面方式查找所有注入value类型的bean,将bean的name作为key,bean对象作为value,放在HashMap中,然后注入。

@Autowired查找候选者可以简化为下面这样

按类型找->通过限定符@Qualifier过滤->@Primary->@Priority->根据名称找(字段名称或者方法名称)

概括为:先按类型找,然后按名称找

案例1:@Autowired标注在构造器上,通过构造器注入依赖对象

Service1

package com.javacode2018.lesson001.demo26.test0;

import org.springframework.stereotype.Component;

@Component

public class Service1 {

}

Service2

package com.javacode2018.lesson001.demo26.test0;

import org.springframework.stereotype.Component;

@Component

public class Service2 {

private Service1 service1;

public Service2() { //@1

System.out.println(this.getClass() + “无参构造器”);

}

public Service2(Service1 service1) { //@2

System.out.println(this.getClass() + “有参构造器”);

this.service1 = service1;

}

@Override

public String toString() { //@2

return “Service2{” +

“service1=” + service1 +

‘}’;

}

}

Service2中依赖于Service1,有2个构造方法

@1:无参构造器

@2:有参构造器,可以通过这个传入依赖的Service1

@3:重写了toString方法,一会打印测试的时候方便查看

来个总的配置文件

package com.javacode2018.lesson001.demo26.test0;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan //@1

public class MainConfig0 {

}

@1:会自动扫描当前类所在的包,会将Service1和Service2注册到容器。

来个测试用例

package com.javacode2018.lesson001.demo26;

import com.javacode2018.lesson001.demo26.test0.MainConfig0;

import org.junit.Test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class InjectTest {

@Test

public void test0() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig0.class);

for (String beanName : context.getBeanDefinitionNames()) {

System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));

}

}

}

main方法中启动容器,加载MainConfig0配置类,然后输出容器中所有的bean

运行部分输出

class com.javacode2018.lesson001.demo26.test0.Service2无参构造器

service1->com.javacode2018.lesson001.demo26.test0.Service1@4a94ee4

service2->Service2{service1=null}

输出中可以看出调用了Service2的无参构造器,service2中的service1为null

通过@Autowired指定注入的构造器

在Service2有参有参构造器上面加上@Autowired注解,如下:

@Autowired

public Service2(Service1 service1) {

System.out.println(this.getClass() + “有参构造器”);

this.service1 = service1;

}

再次运行test0()

class com.javacode2018.lesson001.demo26.test0.Service2有参构造器

service1->com.javacode2018.lesson001.demo26.test0.Service1@4ec4f3a0

service2->Service2{service1=com.javacode2018.lesson001.demo26.test0.Service1@4ec4f3a0}

Service2有参构造器被调用了,service2中的service1有值了。

案例2:@Autowired标注在方法上,通过方法注入依赖的对象

Service1

package com.javacode2018.lesson001.demo26.test1;

import org.springframework.stereotype.Component;

@Component

public class Service1 {

}

Service2

package com.javacode2018.lesson001.demo26.test1;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

@Component

public class Service2 {

private Service1 service1;

@Autowired

public void injectService1(Service1 service1) { //@1

System.out.println(this.getClass().getName() + “.injectService1()”);

this.service1 = service1;

}

@Override

public String toString() {

return “Service2{” +

“service1=” + service1 +

‘}’;

}

}

@1:方法上标注了@Autowired,spring容器会调用这个方法,从容器中查找Service1类型的bean,然后注入。

来个总的配置文件

package com.javacode2018.lesson001.demo26.test1;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan

public class MainConfig1 {

}

来个测试用例

InjectTest中加个方法

@Test

public void test1() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig1.class);

for (String beanName : context.getBeanDefinitionNames()) {

System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));

}

}

运行输出

com.javacode2018.lesson001.demo26.test1.Service2.injectService1()

service1->com.javacode2018.lesson001.demo26.test1.Service1@9597028

service2->Service2{service1=com.javacode2018.lesson001.demo26.test1.Service1@9597028}

通过injectService1方法成功注入service1

案例3:@Autowired标注在setter方法上,通过setter方法注入

上面2种通过构造器,和通过普通的一个方法注入,不是很常见,可以将@Autowired标注在set方法上面,来注入指定的对象

Service1

package com.javacode2018.lesson001.demo26.test2;

import org.springframework.stereotype.Component;

@Component

public class Service1 {

}

Service2

package com.javacode2018.lesson001.demo26.test2;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

@Component

public class Service2 {

private Service1 service1;

@Autowired

public void setService1(Service1 service1) { //@1

System.out.println(this.getClass().getName() + “.setService1方法”);

this.service1 = service1;

}

@Override

public String toString() {

return “Service2{” +

“service1=” + service1 +

‘}’;

}

}

@1:标准的set方法,方法上使用了 @Autowired,会通过这个方法注入Service1类型的bean对象。

来个总的配置文件

package com.javacode2018.lesson001.demo26.test2;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan

public class MainConfig2 {

}

来个测试用例

@Test

public void test2() {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);

for (String beanName : context.getBeanDefinitionNames()) {

System.out.println(String.format(“%s->%s”, beanName, context.getBean(beanName)));

}

}

运行输出

com.javacode2018.lesson001.demo26.test2.Service2.setService1方法

service1->com.javacode2018.lesson001.demo26.test2.Service1@6069db50

service2->Service2{service1=com.javacode2018.lesson001.demo26.test2.Service1@6069db50}

案例4:@Autowired标注在方法参数上

Service1

package com.javacode2018.lesson001.demo26.

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值