美文网首页
spring 学习总结(二) IOC的初步应用

spring 学习总结(二) IOC的初步应用

作者: 随月踏清风 | 来源:发表于2019-02-11 20:06 被阅读0次
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

IOC的实现原理

Ioc是通过读取配置文件中。然后利用反射机制,在需要的时候获取对象。

在spring中的实现方式如下:

1.使用XML配置、或者注解将对象进行存放。

2.spring容器通过读取配置文件或者元数据创建对象,并将对象存入IoC容器。

3.在使用时,从IoC容器中取出对象。

在网上偷了张图,大致可以描述清楚:

spring 学习总结(二) IOC的初步应用
首先我们需要搭建好spring的运行环境,现在大多是通过maven进行依赖注入,随手在网上找一份即可(以下配置文件转自张果,侵删):
<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>com.zxl</groupId>
  <artifactId>MyProject</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>MyProject</name>
  <url>http://maven.apache.org</url>

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.3.0.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
            <version>4.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>
    </dependencies>
</project>
1.无参构造

在实体类文件夹entity中创建一个Worke类

public class Worker{
    private int userId;
    private String name;
    
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId= userId;
    }

    public  String getName(){
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

在spring.xml文件中配置bean标签,bean中id表示对象名,class表示模板类:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
         <!-- 配置Worker对象-->
     <bean id="worker1" class="com.zxl.entity.Worker"></bean>
</beans>

调用API获取对象,通过id获取对象:

public class Test {
    public static void main(String[] args) {
        //1.加载spring.xml配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        //2.通过id值获取对象
        Worker worker1 = (Worker) applicationContext.getBean("worker1");
        System.out.println(worker1);
    }
}

此处创建对象并非用new创建,而是通过读取配置文件,利用反射机制创建

以上程序打印出的信息大致如下

Worker {userId=0,name=null}

此处调用了Worke类的无参构造方法,只会创建对象,不会赋值。需要赋值可以进行配置。

<?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">

     <!-- 配置worker对象 -->
     <bean id="worker1" class="com.zxl.entity.Worker">
        <property name="userId" value="32"></property>
        <property name="name" value="随月踏清风"></property>
     </bean>

</beans>

此时打印的结果为:

Worker {userId=32 name=随月踏清风}

无参构造赋值是通过调用setter方法,因此getter方法可以不要,但是setter方法不能省略。

2.有参构造

有无参构造,就有有参构造。有参构造,顾名思义就是在类中加入有参构造方法。代码如下:

public class Worker{
    private int userId;
    private String name;
    
    public Worker(int userId,String name){
        this.userId = userId;
        this.name = name;
    }
}

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">

     <!-- 通过有参构造函数创建对象 -->
     <bean id="worker1" class="com.zxl.entity.Worker">
        <constructor-arg name="userId" value="32"></constructor-arg>
        <constructor-arg name="name" value="随月踏清风"></constructor-arg>
     </bean>

</beans>

IOC容器根据constructor-arg标签加载对应的有参构造函数,创建对象并完成属性赋值。如果不想通过name进行参数赋值,可以利用索引index进行对应,如下:

<bean id="worker1" class="com.zxl.entity.Worker">
        <constructor-arg index="0" value="32"></constructor-arg>
        <constructor-arg index="1" value="随月踏清风"></constructor-arg>
</bean>

以上方法从容器中获取的对象都是单例对象,不管创建多少个,指向的都是同一个,如下面的例子

ApplicationContext ctx=newClassPathXmlApplicationContext("spring.xml");
Worker worker1=ctx.getBean("worker1");
Worker worker2=ctx.getBean("worker1");
System.out.println(worker1==worker2)

显而易见,打印的结果是true。想一个bean对象对应多个,可以使用scope指定作用域。

spring 学习总结(二) IOC的初步应用
修改配置文件如下:
<bean id="worker1" class="com.zxl.entity.Worker" scope="prototype">
<constructor-arg index="0" value="32"></constructor-arg>
<constructor-arg index="1" value="随月踏清风"></constructor-arg>
</bean>

若此时再次运行测试代码,运行结果为false。
需要说明的是,指定bean的时候,可以用id和(或)name,两者都可以找到指定的bean,但是也存在一部分差异,此处不做过多说明。

IOC是spring的核心,spring中控制层、业务层、持久层都是通过IOC完成依赖注入的,本文只针对ioc的简单应用进行了整理,更多用法还需要继续学习。

相关文章

网友评论

      本文标题:spring 学习总结(二) IOC的初步应用

      本文链接:https://www.haomeiwen.com/subject/duhceqtx.html