基础8:注解详解(自动装配)

@Autowired自动装配

@Autowired不仅可以注解属性,还可以注解普通方法、构造器方法、还有方法参数。

当@Autowired注解属性时,遵循如下逻辑:

①优先按照类型去容器中找对应的组件,找到就赋值;

②如果找到多个相同类型的组件,再将属性名称来作为组件的ID去容器中查找;

③如果想要特定ID的组件来装配,则可以根据@Qualifier注解来明确要求被装配组件的ID名称;或者使用@Primary注解来注解装配的Bean,这样默认就拿这个Bean来装配了;

④@Autowired注解一定要将属性赋值,否则就会报错,可以使用该注解的required属性来设置为可复制,例如:@Autowired(required=false);

当@Autowired注解普通方法时,遵循如下逻辑:

以setPersionDao(PersionDao persionDao)为例来说明:

当@Autowired注解在PersionService.setPersionDao方法上时,Spring容器创建PersionService对象时,就会调用setPersionDao方法来完成赋值,由于setPersionDao方法使用了PersionDao类型的参数persionDao,因此Spring则从IOC容器中获取实例对象(@Autowired注解在方法上与在属性上是一致的);

@Service
public class PersionService {
//    @Autowired(required = false)
//    @Qualifier("persionDao")
//    @Resource
    private PersionDao persionDao;
    public PersionDao getPersionDao() {
        return persionDao;
    }
    @Autowired
    public void setPersionDao(PersionDao persionDao3) {
        this.persionDao = persionDao3;
    }
    @Override
    public String toString() {
        return "PersionService{" +
                "persionDao=" + persionDao +
                '}';
    }
}

 

@Repository
public class PersionDao {}

 

PersionService persionService = applicationContext.getBean(PersionService.class);
System.out.println(persionService.toString());
PersionDao PersionDao2 = (PersionDao) applicationContext.getBean("persionDao2");
System.out.println("persionDao2:" + PersionDao2.toString());
PersionDao2 = (PersionDao) applicationContext.getBean("persionDao");
System.out.println("persionDao:" + PersionDao2.toString());

错误信息:

七月 23, 2020 9:23:46 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext refresh

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionController': Unsatisfied dependency expressed through field 'persionService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionService': Unsatisfied dependency expressed through method 'setPersionDao' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.spring.annotation.PersionDao' available: expected single matching bean but found 2: persionDao,persionDao2

 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionController': Unsatisfied dependency expressed through field 'persionService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionService': Unsatisfied dependency expressed through method 'setPersionDao' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.spring.annotation.PersionDao' available: expected single matching bean but found 2: persionDao,persionDao2

当@Autowired注解构造方法时,遵循逻辑与普通方法一致,只不过有个特殊之处:

如果组件只有一个构造器,且还是有参构造器,则这个构造器无需添加@Autowired注解也能从IOC容器中获取参数,即有参构造方法即便没有@Autowired注解也能从IOC容器中获取参数值;

与之类似的效果@Bean注解也有,只不过@Bean注解必须标注方法,这样才能让方法参数从容器中获取,即使用@Bean注解方法后,可以不再使用@Autowired注解;

@Bean
public PersionService persionService2(PersionDao persionDao){
    PersionService persionService= new PersionService();
    persionService.setPersionDao(persionDao);
    return  persionService;
}

 

public PersionService(PersionDao persionDao) {
this.persionDao = persionDao;
}

//这里为了验证@Bean注解对@Autowired注解的顶替作用,测试的时候先把这个构造方法注释掉

 

@Service

public class PersionService {

    @Autowired(required = false)

    @Qualifier("persionDao")

    private PersionDao persionDao;

    @Override

    public String toString() {

        return "PersionService{" +

                "persionDao=" + persionDao +

                '}';

    }

}

@Repository

@Primary

public class PersionDao {

}

@Resource和@Inject

@Resource:Spring支持JAVA规范自带的JSR250规范,其效果跟@Autowired类似,使用形式如:@Resource(name=”xxxx”),该注解不支持@Primary注解,也不支持@Autowired(required=false);

@Inject:Spring支持JAVA规范自带的JSR330规范,其效果跟@Autowired类似,需要javax.inject包支持,使用形式如:@Inject

Aware接口来自定义组件

通过实现该接口,自定义组件可以直接调用Spring最底层的框架,而Spring框架则根据回调Aware接口里的方法来间接调用自定义组件的方法;

下面是Aware的子接口:

每一个Aware都对应一个AwareProcessor,核心是AwareProcessor来回调Aware,而Aware继续回调用户自己实现的接口方法;

@Profile根据不同环境注册不同组件

①@Profile既可以注解方法,也可以注解类,当注解类的时候,当这个类加载的时候,其内部方法才能生效,否则内部方法无法生效,即便某方法@Profile注解符合被激活的环境;

②没有被@Profile注解的类或方法(前提是当前方法所属类并没有@Profile注解),任何环境下都会被Spring注册;

③@Profile默认环境是default;

那么,如何激活某个环境呢,常用方式有2种:

①使用命令行动态参数方式激活某种环境:

-Dspring.profiles.active=XXX

②使用代码方式激活某种环境:

applicationContext.getEnvironment().setActiveProfiles(XXX);

applicationContext.register(XXX.class);

applicationContext.refresh();

举例:

@Profile("test")
@Bean
public PersionDao persionDao4(){
    PersionDao persionDao = new PersionDao();
    persionDao.setName("张三");
    return  persionDao;
}
@Profile("dev")
@Bean
public PersionDao persionDao5(){
    PersionDao persionDao = new PersionDao();
    persionDao.setName("李四");
    return  persionDao;
}
@Profile("prod")
@Bean
public PersionDao persionDao6(){
    PersionDao persionDao = new PersionDao();
    persionDao.setName("王五");
    return  persionDao;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值