spring学习笔记(spring概述和IOC)

spring5

1、spring的概述

1.1、spring是什么

1.2、spring的优点

  • Spring是一个开源的免费的框架(容器)。
  • spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能(AOP 编程的支持)。
  • 声明式事务的支持,可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
  • Spring 不排斥各种优秀的开源框架,相反 Spring 可以降低各种框架的使用难度(方便集成各种优势框架)。Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
  • Spring 框架运行占用的资源少,运行效率高,不依赖其他 jar(轻量),非侵入式的框架。
  • 提供了 Ioc 控制反转,由容器管理对象及对象的依赖关系(针对接口编程,解耦合)。
  • Java 源码是经典学习范例,Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

1.3、spring的体系结构
在这里插入图片描述
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
在这里插入图片描述

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

2. spring的第一个程序

2.1、环境搭建
导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>

说明:导入spring-webmvc的依赖,其中包含了

  • org.springframework:spring-aop:5.2.0.RELEASE
  • org.springframework:spring-beans:5.2.0.RELEASE
  • org.springframework:spring-context:5.2.0.RELEASE
  • org.springframework:spring-core:5.2.0.RELEASE
  • org.springframework:spring-expression:5.2.0.RELEASE
  • org.springframework:spring-web:5.2.0.RELEASE

HelloSpring:

@Data
public class HelloSpring {
    private String say;
}

spring配置文件:applicationContext.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="hello" class="com.wjh.HelloSpring"/>

</beans>

说明:把对象的创建改为以文件配置对象,并把对象存进容器,以后对象就交给spring容器来管理。

测试:

public class HelloTest {

    private ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    @Test
    public void testhello(){
        HelloSpring hello = (HelloSpring) context.getBean("hello");
        hello.setSay("你好,spring");
        System.out.println(hello.toString());
    }
}

测试结果:
在这里插入图片描述

3、IOC控制反转

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”?

  • 谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
  • 为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

就是说,以后对象的创建、管理、注销等等这个生命周期都交给容器来管理。

3.1 IOC创建对象的方式

1、 使用无参构造对象,默认。

User:

package com.wjh.domain;

public class User {
    private String name;
    public User(){
        System.out.println("使用了无参构造方法");
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

<!--配置user实列-->
    <bean id="user" class="com.wjh.domain.User"></bean>

测试:

@Test
    public void testUser(){
        User user = (User) context.getBean("user");
    }

测试结果:
在这里插入图片描述

2 、使用有参构造方法

  1. 下标赋值
 <bean id="user" class="com.wjh.domain.User">
        <constructor-arg index="0" value="张三"></constructor-arg>
    </bean>
  1. 类型赋值
<!--类型赋值-->
    <bean id="user" class="com.wjh.domain.User">
        <constructor-arg type="java.lang.String" value="张三"></constructor-arg>
    </bean>
  1. 参数名赋值
 <!--参数名赋值-->
    <bean id="user" class="com.wjh.domain.User">
        <constructor-arg name="name" value="张三"></constructor-arg>
    </bean>

测试:

   @Test
    public void testUser(){
        User user = (User) context.getBean("user");
        System.out.println(user);
    }

测试结果:
在这里插入图片描述
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了。

4、spring的配置

4.1:别名
  <!--配置别名-->
    <alias name="user" alias="user2"></alias>
4.2:Bean的配置
  • id: bean的唯一标识。
  • class: bean对象对应的全限定类名。
  • name:别名。
  • scope:bean的作用域。
4.3:import

导入其他applicationContext.xml配置文件。

5、DI依赖注入

DI注入定义:bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。

  • 依赖:bean对象的创建依赖于容器。
  • 注入:bean对象的所有属性,由容器来注入。
5.1、构造器注入
5.2、Set方式注入(掌握)

实体类Student:

@Data
@NoArgsConstructor
@AllArgsConstructor
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 String wife;
    private Properties pros;
}

实体类Address:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Address {
    private String address;
}

配置文件applicationContext.xml

<bean id="address" class="com.wjh.domain.Address">
        <property name="address" value="广东省"/>
    </bean>

    <bean id="student" class="com.wjh.domain.Student">

        <property name="name" value="张三"/>

        <!--对象引用-->
        <property name="address" ref="address"/>
        <!--数组赋值-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>
        <!--List赋值-->
        <property name="hobbys">
            <list>
                <value>篮球</value>
                <value>唱歌</value>
                <value>跳舞</value>
                <value>打代码</value>
            </list>
        </property>
        <!--map集合赋值-->
        <property name="card">
            <map>
                <entry key="身份证" value="112233"></entry>
                <entry key="一卡通" value="123456"></entry>
            </map>
        </property>
        <!--Set集合赋值-->
        <property name="games">
            <set>
                <value>绝地求生</value>
                <value>英雄联盟</value>
                <value>王者荣耀</value>
            </set>
            <!--null值赋值-->
        </property>
        <property name="wife">
            <null></null>
        </property>
        <!--Properties赋值-->
        <property name="pros">
            <props>
                <prop key="学号">12346789</prop>
                <prop key="性别"></prop>
                <prop key="生日">1998-05-20</prop>
            </props>
        </property>
    </bean>

测试:

 @Test
    public void testStudent(){
        Student student = (Student) context.getBean("student");
        System.out.println(student);

    }

测试结果:

Student(name=张三, address=Address(address=广东省), books=[红楼梦, 西游记, 水浒传, 三国演义], hobbys=[篮球, 唱歌, 跳舞, 打代码], card={身份证=112233, 一卡通=123456}, games=[绝地求生, 英雄联盟, 王者荣耀], wife=null, pros={学号=12346789, 生日=1998-05-20, 性别=})
5.3、扩展方式注入

有对于设值注入与构造注入,在配置文件中,除了使用或标签外,还可使用命名空间注入的方式,让注入的值以标签属性的方式出现。

根据注入实现方式的不同,分为 p 命名空间注入与 c 命名空间注入。

p 命名空间注入:采用设值注入方式,故需要有相应的 setter

c 命名空间注入:采用构造注入方式,故需要有相应的构造器

  • p 命名空间注入:
<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 name="classic" class="com.example.ExampleBean">
        <property name="email" value="someone@somewhere.com"/>
    </bean>

    <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="someone@somewhere.com"/>
</beans>
  • c 命名空间注入
    修改配置文件头,即添加相应约束xmlns:c=“http://www.springframework.org/schema/c”
 <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="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>

    <!-- traditional declaration with optional argument names -->
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg name="thingTwo" ref="beanTwo"/>
        <constructor-arg name="thingThree" ref="beanThree"/>
        <constructor-arg name="email" value="something@somewhere.com"/>
    </bean>

    <!-- c-namespace declaration with argument names -->
    <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
        c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

</beans>

6、bean的作用域

在这里插入图片描述

1、Singleton Scope:单例模型(spring默认机制)
  • 只有一个单例 bean 的共享实例被管理,并且所有对带有一个或多个 ID 与该 bean 定义匹配的 bean 的请求都会导致Spring 容器返回一个特定的 bean 实例。
  • 换句话说,当您定义一个 bean 定义并且它的作用域是一个单例时,Spring IoC 容器会创建该 bean
    定义定义的对象的一个​​实例。该单个实例存储在此类单例 bean 的缓存中,并且对该命名 bean
    的所有后续请求和引用都返回缓存对象。下图显示了单例范围的工作原理:
    在这里插入图片描述
<bean id="user" class="com.wjh.domain.User" scope="singleton">
        <constructor-arg name="name" value="张三"></constructor-arg>
    </bean>

测试:

 @Test
    public void testScope(){
        Object user = context.getBean("user");
        Object user2 = context.getBean("user");
        System.out.println(user == user2);
    }

测试结果:

true
2、Prototype Scope:原型范围
  • bean 部署的非单一原型范围导致每次对特定 bean 发出请求时都会创建一个新 bean 实例。也就是说,bean 被注入到另一个 bean 中,或者您通过getBean()容器上的方法调用来请求它。通常,您应该对所有有状态 bean 使用原型作用域,对无状态 bean 使用单例作用域。
  • 在这里插入图片描述
<bean id="user" class="com.wjh.domain.User" scope="prototype">
        <constructor-arg name="name" value="张三"></constructor-arg>
    </bean>

测试结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值