@Autowired自动注入、@Qualifier指定值、@Primary高优先级、@Resource 自动注入、 @Inject自动注入


自动装配(自动注入);
Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;

1)、@Autowired:自动注入:
1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id(beanName)去容器中查找
applicationContext.getBean("bookDao")
3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id(beanName),而不是使用属性名
        4)、自动装配默认一定要将属性赋值好,没有就会报错;
可以使用@Autowired(required=false) 是false那么容器中可以没有这个bean,返回的是空值,也不会报异常;
5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
也可以继续使用@Qualifier指定需要装配的bean的名字
顺序 第一是@Qualifier 指定值 第二是@Primary 高优先级 第三根据@Autowired自身的筛选规则

2)、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
1)、@Resource:
   可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
  没有能支持@Primary功能没有支持@Autowired(reqiured=false);
  2)、@Inject:
   需要导入javax.inject的包,和Autowired的功能一样可以和@Primary一起使用。没有required=false的功能
    @Autowired:Spring定义的; @Resource、@Inject都是java规范
3)、 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值
1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
3)、放在参数位置:上面两种情况中参数中都默认有@Autowired,只是默认不写效果一样。
4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware
把Spring底层一些组件注入到自定义的Bean中;
xxxAware:功能使用xxxProcessor;
  ApplicationContextAware==》ApplicationContextAwareProcessor;
 

 

 

@Autowired自动注入

配置类

@Service
public class DemoService {

    @Autowired
    private DemoDao demoDao;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao +
                '}';
    }
}
@Repository
@Data
public class DemoDao {

    private String flag = "1";
}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {

}

输出

@Test
    public void Test1(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig3.class);
        DemoService demoService = applicationContext.getBean(DemoService.class);
        System.out.println(demoService);
    }

输出结果

 

 

我们在创建一个类型也是DemoDao放入容器中 修改service中注入dao的name 

看输出结果

@Repository
@Data
public class DemoDao {

    private String flag = "1";
}
@Service
public class DemoService {

    @Autowired
    private DemoDao demoDao2;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao2 +
                '}';
    }

}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {

    @Bean("demoDao2")
    public DemoDao demoDao(){
        DemoDao demoDao = new DemoDao();
        demoDao.setFlag("2");
        return demoDao;
    }
}

输出

复用上面输出代码

输出结果 找到了demoDao2  结论 先去容器中根据类型找,找到后在根据beanName筛选

 

 

 @Qualifier指定值

@Service
public class DemoService {

    @Qualifier("demoDao2")
    @Autowired
    private DemoDao demoDao;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao +
                '}';
    }

}
@Repository
@Data
public class DemoDao {

    private String flag = "1";
}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {

    @Bean("demoDao2")
    public DemoDao demoDao(){
        DemoDao demoDao = new DemoDao();
        demoDao.setFlag("2");
        return demoDao;
    }
}

输出

复用上面输出代码

输出结果

 

 

 @Primary高优先级

配置类

@Repository
@Data
@Primary
public class DemoDao {

    private String flag = "1";
}
@Service
public class DemoService {

    @Autowired
    private DemoDao demoDao2;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao2 +
                '}';
    }

}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {
  
//@Primary @Bean(
"demoDao2") public DemoDao demoDao(){ DemoDao demoDao = new DemoDao(); demoDao.setFlag("2"); return demoDao; } }

输出

复用上面输出代码

输出结果

 

@Resource (java的自动注入注解)

@Repository
@Data
public class DemoDao {

    private String flag = "1";
}
@Service
public class DemoService {
   // 不写name用下面的属性值筛选
    @Resource(name = "demoDao")
    private DemoDao demoDao2;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao2 +
                '}';
    }

}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {

    @Bean("demoDao2")
    public DemoDao demoDao(){
        DemoDao demoDao = new DemoDao();
        demoDao.setFlag("2");
        return demoDao;
    }
}

输出

复用上面输出代码

输出内容

 

 

 @Inject(java的自动注入注解 需要引入jar包)

@Repository
@Data
@Primary
public class DemoDao {

    private String flag = "1";
}
@Service
public class DemoService {

    @Inject
    private DemoDao demoDao2;

    @Override
    public String toString() {
        return "DemoService{" +
                "demoDao=" + demoDao2 +
                '}';
    }

}
@Configuration
@ComponentScan(value = {"com.example.demo.study.dao","com.example.demo.study.service"})
public class MyConfig3 {

    @Bean("demoDao2")
    public DemoDao demoDao(){
        DemoDao demoDao = new DemoDao();
        demoDao.setFlag("2");
        return demoDao;
    }
}

输出

复用上面输出代码

输出结果

 

 

 @Autowired标注在构造器、参数、方法;

配置类

@Configuration
@ComponentScan(value = {"com.example.demo.study.entity.ent"})
public class MyConfig4 {

    /*
     * 标注的方法创建对象的时候,方法参数的值从容器中获取
     * 也可以标注标注在参数前面 默认是不标注
     */
    @Bean
    @Autowired
    public Entity3 entity3(Pet pet){
        Entity3 entity3 = new Entity3();
        entity3.setPet(pet);
        return entity3;
    }
}
@Component
@Data
public class Entity2 {

    private Pet pet;

    //构造器要用的组件,都是从容器中获取
    @Autowired
    public Entity2(Pet pet) {
        this.pet = pet;
    }

    //标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值;
    //方法使用的参数,自定义类型的值从ioc容器中获取
    //@Autowired
    public void setPet(Pet pet) {
        this.pet = pet;
    }

    @Override
    public String toString() {
        return "Entity2{" +
                "pet=" + pet +
                '}';
    }
}
@Component
@Data
public class Entity3 {

    private Pet pet;

    @Override
    public String toString() {
        return "Entity3{" +
                "pet=" + pet +
                '}';
    }
}

输出

 @Test
    public void Test1(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig4.class);
        // 标注有参构造器
        Entity2 entity2 = applicationContext.getBean(Entity2.class);
        System.out.println(entity2);
        // 标注在方法上
        Entity3 entity3 = applicationContext.getBean(Entity3.class);
        System.out.println(entity3);
        Pet pet = applicationContext.getBean(Pet.class);
        System.out.println(pet);
    }

输出结果

Aware注入Spring底层组件

配置类

@Configuration
@ComponentScan(value = {"com.example.demo.study.entity.ent1"})
public class MyConfig5 {

}
@Component
public class Entity8 implements ApplicationEventPublisherAware,ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {

    private ApplicationContext applicationContext;

    private ApplicationEventPublisher applicationEventPublisher;

    // ApplicationContextAware
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("传入的ioc:"+applicationContext);
        System.out.println("applicationContext与applicationEventPublisher对比"+(applicationContext == applicationEventPublisher));
    }

    // BeanNameAware
    @Override
    public void setBeanName(String name) {
        System.out.println("当前bean的名字:"+name);
    }

    // EmbeddedValueResolverAware
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String resolveStringValue = resolver.resolveStringValue("你好 我是${os.name} 年龄#{10*10}");
        System.out.println("解析的字符串:"+resolveStringValue);
    }

    // ApplicationEventPublisherAware
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("setApplicationContext之前调用"+applicationEventPublisher);
        this.applicationEventPublisher = applicationEventPublisher;
    }

}

输出

  @Test
    public void Test1(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig5.class);
        // 标注有参构造器
        Entity8 entity8 = applicationContext.getBean(Entity8.class);
        System.out.println(applicationContext);
    }

输出结果

 

posted @ 2022-06-05 08:11  Dabo丶  阅读(662)  评论(0编辑  收藏  举报