欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring学习(1)之IoC和Di

程序员文章站 2022-06-22 16:09:46
...

1.Spring

1.1简介
  1. 是一个大杂烩,使现有的技术更快的使用,整合了现有的所有的框架。
  2. 2002年,首次推出了SPring的框架的雏形:interface21框架。
  3. 创始人:Rod Johnson,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。提出了著名的造*的理论。

现在的技术栈普遍是:

  1. SSH : Struct2 + Spring + Hibernate!
  2. SSM : SpringMvc + Spring + Mybatis!

Spring的获取的来源

官网:https://spring.io/projects/spring-framework#overview

官方下载地址: http://repo.spring.io/release/org/springframework/spring

GitHub:https://github.com/spring-projects/spring-framework

Spring的jar包:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>
// 后期使用的时候,会对数据库进行相关的操作
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>
1.2优点与缺点:

优点:

Spring是一个轻量级的控制反转(ioc)和面向切面编程(aop)的框架。

  1. 开源性
  2. 轻量级的,非入侵式的。
  3. 控制反转和,面向切面编程的。
  4. 支持对事务的处理,对框架的支持。

缺点:

配置十分的繁琐,被称为配置地狱。

1.3组成:

Spring学习(1)之IoC和Di

  • Data Access/Integration层包含有JDBC、ORM、OXM、JMS和Transaction模块。
  • Web层包含了Web、Web-Servlet、WebSocket、Web-Porlet模块。
  • AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现。
  • Core Container(核心容器):包含有Beans、Core、Context和SpEL模块。
  • Test模块支持使用JUnit和TestNG对Spring组件进行测试。
1.4提前知识:
  1. 现阶段的java开发会逐渐朝面向Spring开发进行。
  2. Springboot:
    1. 一个快速开发的一个脚手架(死模板,只需要记下来就好)
    2. 基于Springboot快速开发单个微服务。
    3. 约定大于配置?
  3. Spring Cloud:是基于Sping Boot 开发的

学习Spring boot最好的前提是学习Spring,只会使用Springboot不知道底层的原理,难以发展。

Spring学习(1)之IoC和Di

2.IoC的本质

中文的意思为控制反转,也可以将他理解为一个容器。

  • 是一种的设计的思想,就是将原本在程序中创建对象的控制权,交由Spring框架进行管理。
  • 正常控制:new一个对象
  • 反控:如果要使用某个对象,是需要只需要从Spring容器获取需要使用的对象,不用关心对象的创建的过程,也就是将创建对象的控制权交给Spring框架。

Spring学习(1)之IoC和Di

示例:

  1. 创建一个Maven项目:

  2. 导入jar包:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
    
  3. 创建一个pojo类,使用了lombok

    @Data
    public class Student implements Serializable {
        private int age;
        private String name;
        private char sex;
    }
    
  4. 再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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="student" class="com.g.pojo.Student">
            <property name="age" value="100"/>
            <property name="name" value="李四"/>
            <property name="sex" value=''/>
        </bean>
    </beans>
    

    id就是对象的名字

  5. 再测试类中进行测试,获取到了该对象

    public class MyTest {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = context.getBean("student", Student.class);
            System.out.println(student);
        }
    }
    

IoC的本质:Spring作为一个容器,需要shenm对象,由Spring进行创建,Spring底层会根据反射的原理找到对象的calss文件并对其中的字段进行赋值等操作(装配,依赖注入)。总之Ioc就是一种设计思想,di(依赖注入)是实现这种思想的一种方法。

2.1IoC创建对象的方式:

因为再实体类中不止有有参的构造也有无参构造,Spring会对创建的实体类进行装配时,会找不到Spring所需要的格式。

  • 无参构造,和上面的例子一样的操作
  • 有参构造,这个时候就需要使用构造器的方式进行属性的注入

例如:

对上面的xml文件进行修改:

<bean id="student" class="com.g.pojo.Student">
    方法1:使用参数的下角标进行依赖注入值
    <constructor-arg index="0" value="200"/>
    方式2:使用参数的名称依赖植入
    <constructor-arg name="name" value="王五"/>
    方式3:使用参数的类型进行依赖注入(不推荐,因为肯定会重复的)
    <constructor-arg type="char" value=''/>
</bean>

3.Spring中xml文件中的属性的配置

3.1别名

xml文件:

<!--就是拓展了上面bean中的id的值-->
<alias name="student" alias="s"/>

测试类:

Student student = context.getBean("s", Student.class);
3.2Bean的配置
<!--
    id : bean 的唯一标识符,也就是相当于我们学的对象名
    class : bean 对象所对应的全限定名 : 包名 + 类型
    name :也是别名,而且name 可以同时取多个别名
    -->
<bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3;u4">
    <property name="name" value="西部开源"/>
</bean>
3.3import

这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个

假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!

  • 张三

  • 李四

  • 王五

  • applicationContext.xml

    <import resource="beans.xml"/>
    <import resource="beans2.xml"/>
    <import resource="beans3.xml"/>
    

使用的时候,直接使用总的配置就可以了

每个人只需要写自己的实体类和xml配置文件就可以了。

3.4bean标签的作用域

Spring学习(1)之IoC和Di

  1. 单例模式 (Spring默认机制)

    <bean id="s1" class="com.g.pojo.Student" scope="singleton"/>
    
  2. 原型模式:每次从容器中get的时候,都会产生一个新对象!

    <bean id="s3" class="com.g.pojo.Student" scope="prototype"/>
    

    测试:

    public class MyTest {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student1 = context.getBean("s1", Student.class);
            Student student2 = context.getBean("s2", Student.class);
            Student student3 = context.getBean("s3", Student.class);
            //单例和单例
            System.out.println(student1==student1);
            //单例和原型
            System.out.println(student1==student3);
        }
    }
    
    true
    false
    
  3. 其余的 request、session、application、这些个只能在web开发中使用到!

4.Di【依赖注入】

4.1.普通注入,无参的bean
4.2.构造器注入:针对于有参构造
<bean id="student" class="com.g.pojo.Student">
    方法1:使用参数的下角标进行依赖注入值
    <constructor-arg index="0" value="200"/>
    方式2:使用参数的名称依赖植入
    <constructor-arg name="name" value="王五"/>
    方式3:使用参数的类型进行依赖注入(不推荐,因为肯定会重复的)
    <constructor-arg type="char" value=''/>
</bean>
4.3.Set方式注入(引用型数据类型)

复杂的实体类的数据的注入

  1. Student类

    public class Student {
        private Address address;
        private String name;
    }
    
  2. Address类

    @Data
    public class Address {
        private String address;
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
  3. 配置文件

    <bean id="dizhi" class="com.g.pojo.Address">
        <property name="address" value="陕西"/>
    </bean>
    <bean id="student" class="com.g.pojo.Student">
        <property name="address" ref="dizhi"/>
        <property name="name" value="张三"/>
    </bean>
    

    注意:student类的指向ref指向上面由Spring创建出来的对象dizhi

  4. 测试

    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) context.getBean("student");
            System.out.println(student);
        }
    }
    
  5. 执行结果

    Student{address=Address(address=陕西)}
    
4.4复杂数据类型的属性注入
  1. 实体类:

    @Data
    public class Student {
        private String name;
        private String[] books;
        private List<String> hobbys;
        private Map<String,String> card;
        private Set<String> games;
        private String wife;
        private Properties info;
    }
    
  2. 配置文件:

    <bean id="student" class="com.g.pojo.Student">
        <property name="name">
            <value>张三</value>
        </property>
        <!--数组-->
        <property name="books">
            <array>
                <value>天龙八部</value>
                <value>笑傲江湖</value>
            </array>
        </property>
        <!--list集合-->
        <property name="hobbys">
            <list>
                <value>running</value>
                <value>swimming</value>
                <value>singing</value>
            </list>
        </property>
        <!--map集合-->
        <property name="card">
            <map>
                <entry key="id" value="123456789"/>
                <entry key="name" value="张三"/>
                <entry key="sex" value=""/>
            </map>
        </property>
        <!--set集合-->
        <property name="games">
            <set>
                <value>lol</value>
                <value>csgo</value>
            </set>
        </property>
        <!--null注入-->
        <property name="wife">
            <null/>
        </property>
        <!--properties-->
        <property name="info">
            <props>
                <prop key="driver">driver</prop>
                <prop key="url">ssss</prop>
                <prop key="username">name</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
    
  3. 测试:

    public class MyTest {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student) context.getBean("student");
            System.out.println(student);
        }
    }
    
4.5拓展方式注入(c和p注入)
  • p命名空间注入,是普通注入的捷径
    在配置文件中导入头文件,然后使用

    头文件:xmlns:p="http://www.springframework.org/schema/p"
    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
            <bean id="student" class="com.g.pojo.Student" p:name="李四"/>
    </beans>
    
  • c命名空间的注入,是构造器注入的捷径,
    使用方法:同理

    头文件:xmlns:c="http://www.springframework.org/schema/c"
    <?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:c="http://www.springframework.org/schema/c"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
            <bean id="student" class="com.g.pojo.Student" c:name="张三"/>
    </beans>
    

上一篇: 影坛恒星

下一篇: 最坏的打算