由浅入深Spring之xml和注解注入

在上一小节中,我们阐述了Spring中的核心思想IOC,那么在Spring中是如何实现IOC思想的呢?

在Spring中通过DI(依赖注入)的方式实现IOC,具体分为两种方法:xml注入和注解注入。

首先,看一下整个项目的整体框架。

entity目录存放实体类,分别有Car抽象类和Person抽象类。CarImpl目录下存放Car的实现类,PersonImpl目录下存放Person的实现类。

main目录存放主函数。

resoucrces目录存放资源配置,目前只存放spring的配置文件。

pom.xml为maven的配置文件。

首先,我们需要导入Spring框架所需要的包,一共有以下几种。

其中spring-context包需要依赖右边四个包,所以我们只需要在maven中添加spring-context依赖就会自动导入Spring所有包。其pom.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spring</groupId>
    <artifactId>spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
    </dependencies>

</project>

 配置完Spring框架后,就要实现注入。首先先实现第一种注入方式xml注入。

之前我们说过,要将对象的控制权交由Spring容器处理,如果使用xml实现,首先得创建一个spring xml的配置文件,其结构如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


</beans>

这是系统自动写好的开头,我们需要在<beans>标签中添加我们的对象。回到上一小节的例子,张三想要开车回家,那么我们首先要先获取车这个对象,那么我们先把所有车交由Spring管理。这里用到<bean>标签:

<bean id="carA" class="entity.CarImpl.CarA"></bean>
<bean id="carB" class="entity.CarImpl.CarB"></bean>

<bean>标签这里用到两个属性,第一个id即为实例的名字,第二个class即为你要交由Spring管理的类。这样我们就将A车和B车对象都交由Spring容器管理。

接着我们需要一个ZhangSan对象,使用相同<bean>标签:

<bean id="ZhangSan" class="entity.PersonImpl.ZhangSan">
     <constructor-arg name="car" ref="carA"/>
</bean>

这里有所不同,id和class和上述一样,但在<bean>标签中还有<constructor-arg>子标签。我我们想象一下,如果我们亲手new一个对象,就会使用到构造器,那么这里也同样的道理,在将对象创建时,有时可能会使用有参数的构造器,那么就会用到<constructor-arg>标签实现构造器注入,这个标签必须与类中构造器相匹配,即相当是调用这个构造器:

public class ZhangSan extends Person {
    ……

    ZhangSan(Car car){
        this.car = car;
    }
    ……
}

因为这里的car为引用类型,所以使用ref属性,其值carA指的是上面id=carA的对象。如果想要初始化的值为int等普通类型,则使用属性value,直接赋值。

有时后可能没有在构造器中实现注入,还可以使用set方法注入:

<bean id="ZhangSan" class="entity.PersonImpl.ZhangSan">
     <property name="car" ref="carA" />
</bean>

这里使用了<property>标签,必须要求类中有对应的set方法,效果和构造器注入相同,即相当于使用了这个方法:

public class ZhangSan extends Person {

    ……
    public void setCar(Car car)
    {
        this.car = car;
    }
    ……
}

此时我们将carA、carB、ZhangSan都交由Spring管理,不用我们手动创建对象了,那么我们该如何拿到这些对象呢?

在主函数中,分为两步:第一、获取到Spring上下文。第二、从Spring上下文的容器中获取对象。

public class Main {
    public static void main(String[] args) {
        //1、获取spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //2、获取ZhangSan对象
        Person ZhangSan = context.getBean("ZhangSan", ZhangSan.class);
        
        ZhangSan.goHome();

    }
}

其中 ClassPathXmlApplicationContext类从类名就可以看出,它是通过xml配置文件中加载Spring上下文的,所以只需把xml文件名传入就可以获取了上下文。得到Spring上下文,意味着得到了Spring的“心脏”,通过上下文的getBean()方法可以获取对象,其中第一个参数为之前配置的对象的id,第二个参数为实体类的class对象。接着就可以执行对应的方法得到结果:

这就完成了xml实现注入,然而大量的配置文件总是麻烦的,在大多数情况下我们通常会使用第二种简洁的方法,用注解实现注入。 这时我们就不用大量配置xml文件了。直接定位到想要交由Spring管理的类,以CarA为例:

@Component(value = "carA")
public class CarA extends Car {
    
    @Override
    public void start() {
        System.out.println("carA is starting!");
    }

    @Override
    public void turnLeft() {
        System.out.println("carA is turning left!");
    }

    @Override
    public void turnRight() {
        System.out.println("carA is turning right!");
    }

    @Override
    public void stop() {
        System.out.println("carA is stopping!");
    }
}

只需在CarA类名上面添加一个注解@ Component就实现了相当于xml中的<bean>标签,其中的value即使实例的名字,相当于xml中的id。对比复杂的xml配置,注解的方式清晰明了。同样对于ZhangSan类:

@Component("ZhangSan")
public class ZhangSan extends Person {

    @Autowired
    @Qualifier(value = "carA")
    private Car car;

    ZhangSan(Car car){
        this.car = car;
    }

    ……
}

通过 @ Component注解把ZhangSan类交由Spring管理,然后直接在Car的属性上添加注解实现初始化。@Autowired注解可以实现自动注入,它会从Spring容器中寻找与此类型相匹配的对象注入进去,在Spring容器中我们有CarA和CarB都可以注入,此时存在不唯一性,于是使用@Qualifier注解实现指定注入,这里我们要求张三开A车回家,就指定value = CarA进行注入。

此时把所有对象都交由Spring容器管理,最后还需修改一点点xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="entity"/>

</beans>

标签<context:component-scan>的作用是开启注解扫描,base-package为扫描范围。我们对entity包下全部扫描,就可以实现自动扫描注解然后将对象放入Spring容器中。需要注意的一点是此标签在context包中,所以<beans>标签中需要添加context相关的命名空间。

xml配置好了后,到主函数,主函数无需任何改动直接运行,就可以得到与xml注入相同的效果。

以上就是Spring中的xml注入和注解注入基本使用方法。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值