Spring学习之路——自动装配

Spring学习之路——自动装配

一、Bean的自动装配简介

在Spring中通常有三种装配机制,他们分别是:

  1. 在xml中显式配置
  2. 在java中显式配置
  3. 隐式的bean发现机制和自动装配

我们之前一直在使用第一种xml装配的方式,第二种在之后的我的博客中会提到。
在这里我们主要来聊一聊第三种,自动化的装配bean。

其自动装配要实现两个操作:

  • 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
  • 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;

下面我们通过一个例子来康康吧!!!

二、真实案例

这里我们先写三个类,人,猫,狗三个类。猫和狗都有一个叫(Bark)的方法。人类拥有猫和狗,并写好其中的getter和setter方法

public class Cat {
    public void Bark(){
        System.out.println("miao");
    }
}
public class Dog {
    public void Bark(){
        System.out.println("wang");
    }
}
public class people {
     private Dog dog;
    private Cat cat;

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public people(){

    }
    public people(Dog dog, Cat cat) {
        this.dog = dog;
        this.cat = cat;
    }
}

首先我们还是通过最最最原始的xml方式注入属性。

    <bean class="Cat" id="cat"></bean>
    <bean class="Dog" id="dog"></bean>
    <bean class="people" id="people">
        <property name="cat" ref="cat"></property>
        <property name="dog" ref="dog"></property>
    </bean>

这种方式想必大家已经非常熟悉了,我们测试一下。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {
    public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       people lili = (people) context.getBean("people");
       lili.getCat().Bark();
       lili.getDog().Bark();
    }
}

最后结果也没有问题!
在这里插入图片描述

三、通过ByName、ByType装配

1、autowire byName (按名称自动装配)

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。

采用自动装配将避免这些错误,并且使配置简单化。
而且实现起来也非常简单。
我们先把之前的bean修改一下.

    <bean class="Cat" id="cat"></bean>
    <bean class="Dog" id="dog"></bean>
    <bean class="people" id="people" autowire="byName">
    </bean>

将人类下面的People下面猫狗的注入删掉,增加一个autowire字段,里面填入byName,我们运行一下康康。
在这里插入图片描述
依然没有任何问题,而如果我们将bean中猫和狗的ID改为cat555这种,程序就会报空指针异常。

在这里插入图片描述这是因为因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

2、autowire byType (按类型自动装配)
我们其他代码不变,只是把byName变成byType,程序便能正常运行。
在这里插入图片描述
这是因为按类型装配与其名字没有关系,容器自动将对应类型的bean装配到people中,但是如果我们有两个猫类型的Bean,程序就会报错,因为使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

四、使用注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。

准备工作: 利用注解的方式注入属性。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

然后开启注解支持

<context:annotation-config/>

这里主要来看一看@Autowired和@Resource两大注解。

  • @Autowired是按类型自动转配的,不支持id匹配。

  • 需要导入 spring-aop的包!

这里我们将people方法的set方法注释掉,使用@Autowired注解.

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

public class people {

    @Autowired

     private Dog dog;
    @Autowired
    private Cat cat;

    public Dog getDog() {
        return dog;
    }

//    public void setDog(Dog dog) {
//        this.dog = dog;
//    }

    public Cat getCat() {
        return cat;
    }

//    public void setCat(Cat cat) {
//        this.cat = cat;
//    }

    public people(){

    }
    public people(Dog dog, Cat cat) {
        this.dog = dog;
        this.cat = cat;
    }
}

在这里插入图片描述
发现输出完全没有问题。

之后我们再来看看@Resource

@Resource如有指定的name属性,先按该属性进行byName方式查找装配;
其次再进行默认的byName方式进行装配;
如果以上都不成功,则按byType的方式自动装配。
都不成功,则报异常。

还是原来这个例子,我们把上面的@Autowired改成@Resource,发现运行还是没有问题.

最后我们引用狂言老师对两者区别的总结。
@Autowired与@Resource异同:

  • @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

  • @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false.如:@Autowired(required=false),如果我们想使用名称装配可以结合@Qualifier注解进行使用

  • @Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。
    当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配

它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。
具体大家可以去查看狂言老师的博客
https://blog.kuangstudy.com/index.php/archives/523/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值