Spring学习第一天

Spirng

1、了解Spring

1.1、简介

  • Spring:春天------->给软件行业带来了春天

  • 2002,首次推出了Spring框架的雏形:interface21框架!

  • Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。

  • Rod Johnson ,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。

  • spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!

  • SSH:Struct2+Spring+Hibernate

  • SSM:SpringMvc+Spring+Mybatis

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

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

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

<!-- 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是一个开源的免费的框架!
  • Spring是一个轻量级的、非入侵时的框架!
  • 控制反转(IOC),面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持!

总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架

1.3、组成

在这里插入图片描述

1.4、扩展

在Spring的官网有这个介绍:现代化的Java开发!说白就是基于Spring的开发
在这里插入图片描述

  • Spring Boot
    • 一个快速开发的脚手架。
    • 基于Spring Boot可以快速的开发单个微服务
    • 约定大于配置
  • Spring Cloud
    • Spring Cloud是基于SpringBoot实现的

因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及

SpringMVC!呈上启下的作用

弊端:发展太久之后违背了原来的理念!配置十分繁琐,人称"配置地狱"

2、IOC理论推导

1.UserDao Dao接口

2.UserDaoImpl Dao实现类

3.UserService 业务接口

4.UserServiceImpl 业务实现类

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求取修改源代码!如果

程序代码量十分大,修改一次的成本代价十分昂贵

在这里插入图片描述

我们使用一个Set接口实现,已经发生了革命性的变化!

 private UserDao userDao;

  public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
  • 之前,程序是主动创建对象!控制权在程序猿手上!
  • 使用了set注入后,程序不再具有主动性,而是变成了被动接受对象

这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了!系统的耦合性大大降低~可以更加的专注业务的实现!

这事IOC的原型!

在这里插入图片描述

IOC本质

控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方式,也有人认为DI只是

Ioc的另一种说法。没有Ioc的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,

对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式

反转了。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者和为一体,

Bean的定义信息直接以注解的形式定义在实现类中,从而达到零配置的目的

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反

转的是Ioc容器,其实现方法是依赖注入(Dependency Injection,DI).

3、HelloSpring

@Test
public void test() {
    //获取Spring的上下文对象
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //我们的对象现在都在Spring中的管理了,我们要使用,直接去里面取出来就可以
    Hello hello = (Hello) context.getBean("hello");
    System.out.println(hello.toString());
}

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的

反转:程序本事不创建对象,而变成被动的接受队形

依赖注入:就是利用set方法进行注入的

IOC是一种编程思想,由主动变成被动的接受

OK,到了现在,我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的

ioc,一句话搞定:对象由Spring来创建,管理,装配

4、IOC创建对象的方式

  1. 使用无参构造方法创建对象 默认

    <bean id="user" class="com.wen.pojo.User">
        <property name="name" value="温嘉璐"/>
    </bean>
    
  2. 使用有参构造方法创建对象

    1. 下标赋值

      <bean id="user" class="com.wen.pojo.User">
          <constructor-arg index="0" value="温嘉璐"/>
      </bean>
      
    2. 类型

      <bean id="user" class="com.wen.pojo.User">
              <!--第二种通过类型创建,不建议使用-->
      <constructor-arg type="java.lang.String" value="温嘉璐"/>
      </bean>
      
    3. 参数名

      <!--第三种,直接通过参数名-->
          <bean id="user" class="com.wen.pojo.User">
              <constructor-arg name="name" value="温嘉璐"/>
          </bean>
      

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了

5、Spring配置

5.1、别名

<!-- 别名,如果添加了别名,我们也可以是使用别名获取到这个对象-->
<alias name="user" alias="user2"/>

5.2、Bean的配置

<!--
 id:bean 的唯一标识符,也就是相当于我们学的对象名
 class:bean 对象所对应的全限定名 :包名+类型
 name:也是别名,而且name 可以同时取多个别名
 -->
<bean id="userT" class="com.wen.pojo.UserT" name="t,t1">
    <property name="name" value="温嘉璐"/>
 </bean>

5.3、import

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

假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,

我们可以利用import将所有人的beans.xml合并为一个总的!

  • 张三

  • 李四

  • 王五

  • applicationContext.xml

    <import resource="beans1.xml"/>
    <import resource="beans.xml"/>
    

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

6、依赖注入

6.1、构造器注入

  1. 使用无参构造方法创建对象 默认

    <bean id="user" class="com.wen.pojo.User">
        <property name="name" value="温嘉璐"/>
    </bean>
    
  2. 使用有参构造方法创建对象

    1. 下标赋值

      <bean id="user" class="com.wen.pojo.User">
          <constructor-arg index="0" value="温嘉璐"/>
      </bean>
      
    2. 类型

      <bean id="user" class="com.wen.pojo.User">
              <!--第二种通过类型创建,不建议使用-->
      <constructor-arg type="java.lang.String" value="温嘉璐"/>
      </bean>
      
    3. 参数名

      <!--第三种,直接通过参数名-->
          <bean id="user" class="com.wen.pojo.User">
              <constructor-arg name="name" value="温嘉璐"/>
          </bean>
      

6.2、Set方式注入【重点】

  • 依赖注入:Set注入!

    • 依赖:bean对象的创建依赖于容器!
    • 注入:bean对象中的所有属性,有容器注入
  • Student类

    @Data
    
    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Map<String, String> card;
        private Set<String> games;
        private Properties info;
        private String wife;
    
    
    }
    
  • Address类

    @ToString
    public class Address {
        @Getter
        @Setter
        private String address;
    }
    
  • 普通值注入

    <property name="name" value="温嘉璐"/>
    
  • 引用类型注入

    <bean id="address" class="com.wen.pojo.Address">
        <property name="address" value="黑龙江省大庆市x"/>
    </bean>
      <bean id="student" class="com.wen.pojo.Student">
             <property name="address" ref="address"/>
    </bean>
    
  • 数组

    <bean id="student" class="com.wen.pojo.Student">
    <property name="books">
        <array>
            <value>红楼梦</value>
            <value>西游记</value>
            <value>三国演义</value>
            <value>水浒传</value>
        </array>
    </property>
    </bean>
    
  • List

    <bean id="student" class="com.wen.pojo.Student">
         <property name="hobbys">
                <list>
                    <value>听歌</value>
                    <value>敲代码</value>
                    <value>看电影</value>
                </list>
            </property>
    </bean>
    
  • Map

    <bean id="student" class="com.wen.pojo.Student">
          <property name="card">
                <map>
                    <entry key="身份证" value="454542543437347"/>
                    <entry key="银行卡" value="1451221454512212"/>
                </map>
            </property>
    </bean>
    
  • Set

    <bean id="student" class="com.wen.pojo.Student">
         <property name="games">
                <set>
                    <value>LOL</value>
                    <value>Cf</value>
                </set>
            </property>
    </bean>
    
  • null

    <bean id="student" class="com.wen.pojo.Student">
          <property name="wife">
                <null/>
            </property>
    </bean>
    
  • properties

    <bean id="student" class="com.wen.pojo.Student">
         <property name="info">
                <props>
                    <prop key="学号">0306190266</prop>
                    <prop key="性别"></prop>
                </props>
            </property>
    </bean>
    

6.3、扩展方式注入

我们可以使用p命名空间和c命名空间进行注入

  • p命名空间

    • 先引入p命名空间

      xmlns:p="http://www.springframework.org/schema/p"
      
    • <!--p 命名空间注入,可以注入属性的值:property-->
      <bean id="user" class="com.wen.pojo.User" p:name="温嘉璐" p:age="18"/>
      
  • c命名空间

    • 先引入c命名空间

      xmlns:c="http://www.springframework.org/schema/c"
      
    • <!--c命名空间注入,通过构造器注入:construct-args-->
      <bean id="user2" class="com.wen.pojo.User" c:name="温嘉璐" c:age="18"/>
      

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:beans.xml")
public class MyTest {
    @Autowired
    private User user2;
    @Autowired
    private User user;

    @Test
    public void test() {
        System.out.println(user2);
    }

    @Test
    public void test1() {
        System.out.println(user);
    }
}

注意点:p命名和c命名不能直接使用需要导入xml约束

6.4、bean作用域

ScopeDescription
singleton(默认)将每个 Spring IoC 容器的单个 bean 定义范围限定为单个对象实例。
prototype将单个 bean 定义的作用域限定为任意数量的对象实例。
request将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有一个在单个 bean 定义后面创建的 bean 实例。仅在可感知网络的 Spring ApplicationContext中有效。
session将单个 bean 定义的范围限定为 HTTP Session的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。
application将单个 bean 定义的范围限定为ServletContext的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。
websocket将单个 bean 定义的范围限定为WebSocket的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。
  1. 单例模式 (Spring默认机制)

    <bean id="user" class="com.wen.pojo.User" p:name="温嘉璐" p:age="18" scope="singleton"/>
    
  2. 原型模式:每次从容器中get的时候,都会产生一个新的对象

    <bean id="user" class="com.wen.pojo.User" p:name="温嘉璐" p:age="18" scope="prototype"/>
    
  3. 其余的request、session、application、这些只能在web开发中使用到!

测试:单例和原型

单例模式下返回true

在这里插入图片描述

原型模式下返回false
在这里插入图片描述

7、Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式!
  • Spring会在上下文中自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式

  1. 在xml中显示的配置
  2. 在java中显示配置
  3. 隐式的自动装配bean【重要】

7.1、测试

环境搭建:一个人有两个宠物!

Dog类:

/**
 * @author 20212
 */
public class Dog {
    public void shout(){
        System.out.println("汪汪汪....");
    }
}

Cat类:

/**
 * @author 20212
 */
public class Cat {
    public void shout(){
        System.out.println("喵喵喵....");
    }
}

People类


@Data
public class People {
    private Dog dog;
    private Cat cat;
    private String name;

}

配置bean

<bean id="cat" class="com.wen.pojo.Cat"></bean>
<bean id="dog" class="com.wen.pojo.Dog"></bean>
<bean id="people" class="com.wen.pojo.People">
    <property name="name" value="温嘉璐"/>
    <property name="cat" ref="cat"/>
    <property name="dog" ref="dog"/>
</bean>

测试类

@Test
public void test1() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    People people = context.getBean("people", People.class);
    people.getDog().shout();
    people.getCat().shout();

}

7.2、byName自动装配

 <bean id="cat" class="com.wen.pojo.Cat"></bean>
 <bean id="dog" class="com.wen.pojo.Dog"></bean>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的 bean id!
-->
<bean id="people" class="com.wen.pojo.People" autowire="byName">
    <property name="name" value="温嘉璐"/>
</bean>

7.2、byType自动装配

<bean  class="com.wen.pojo.Cat"></bean>
 <bean class="com.wen.pojo.Dog"></bean>
<!--
byName:会自动在容器上下文中查找,和自己对象属性类型相同的 bean
-->
<bean id="people" class="com.wen.pojo.People" autowire="byType">
    <property name="name" value="温嘉璐"/>
</bean>

小结:

  • byname的是偶,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
 <bean id="cat" class="com.wen.pojo.Cat"></bean>
 <bean id="dog" class="com.wen.pojo.Dog"></bean>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的 bean id!
-->
<bean id="people" class="com.wen.pojo.People" autowire="byName">
    <property name="name" value="温嘉璐"/>
</bean>

7.2、byType自动装配

<bean  class="com.wen.pojo.Cat"></bean>
 <bean class="com.wen.pojo.Dog"></bean>
<!--
byName:会自动在容器上下文中查找,和自己对象属性类型相同的 bean
-->
<bean id="people" class="com.wen.pojo.People" autowire="byType">
    <property name="name" value="温嘉璐"/>
</bean>

小结:

  • byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
  • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值