从0到1学习Spring框架1

简介: 从0到1学习Spring框架

1.Spring简介

1.1.什么是Spring

  • Spring是一个轻量级的框架,能够简化企业级应用开发,减少代码量。

Spring的核心框架是AOP(面向切面)与IOC(控制反转),IOC说白了就是跟容器要对象,DI(依赖注入)就是给属性赋值,AOP就是根据动态代理分为切面,切入点和通知。Spring还提供对JDBC的轻量级封装,还提供声明事务。Spring还根据MVC设计模式开发出SpringMVC框架。

(1)Spring框架目标

  • 使用声明式事务,向EJB挑战
  • 框架整合,像胶水一样整合多个框架.

(2)什么是JavaEE

  • JAVAEE:Java Enterprise Edition(java企业级版本)是Sun制定的一套java开发规范
  • 是由一系列的JSR组成

(3)什么是JSR

  • Java Specification Requests Java规范提案
  • (4)JAVAEE容器和组件

容器

Applet Container

Web Container

Application Client Container

EJB Container

组件

Applet

JSP Servlet

Java Bean

EJB JavaBean

(5)Spring特点

  • Ioc:解耦使用IoC机制避免硬编码造成程序耦合
  • AOP:Aspect Orentied Programing 面向切面的编程
  • 声明式事务管理
  • 对JDBC进行轻量级封装,更加灵活的操作数据库
  • Spring提供MVC模式支持:SpringMVC
  • 提供文件上传,定时器常用工具类
  • 对其他优秀框架的支持(集成其他框架)

1.2.Spring框架结构

5ccc8bf42b7142c392bd0cc24adf48a7.png

(1)Spring的核心功能

  • IoC容器
  • Bean生命周期管理
  • SpEL
  • AOP容器
  • 注解体系
  • 数据验证

(2)Spring的好处

  • 方便解耦
  • AOP编程支持
  • 声明式事务的支持
  • 方便程序的测试
  • 方便集成各种优秀框架
  • 降低JavaEE API的使用难度

2.Spring资源管理

2.1.Spring资源管理简介

(1)Spring资源管理的特点

  • 隐藏底层的实现
  • 新增资源存在判断、资源操作权限相关的功能
  • 支持通配符获取资源

(2)Spring管理哪些资源

  • UrlResource
  • ClassPathResource
  • FileSystemResource
  • ServletContextResource
  • InputStreamResource
  • ByteArrayResource

(3)资源协议与路径

  • classpath:从当前jvm的classpath根路径开始获取资源
  • file:从操作系统的路径获取资源
  • http(s):从互联网获取资源
  • 无标记:根据应用上下文获取资源

(4)Spring使用什么访问底层资源

Spring使用Resource接口访问底层资源

(5)Spring使用什么接口加载资源

Spring使用ResourceLoader接口加载资源

IOC容器实现了ResourceLoader接口,可以随时使用它的**getResource(location)**加载资源

2.2.Spring资源管理案例

  • 创建maven工程,写HelloService
public class HelloService {
    public void sayHello(String name){
        System.out.println(name+":你好!");
    }
}
  • 引入spring-framework依赖
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.15.RELEASE</version>
    </dependency>
</dependencies>
  • 在main/resources下创建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
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="helloService" class="com.tjetc.service.HelloService">
    </bean>
</beans>
  • 编写测试类
public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService helloService = (HelloService) context.getBean("helloService");
        helloService.sayHello("李祥");
    }
}

运行结果

李祥:你好!

3.Spring容器创建

3.1.IOC容器创建的三种方法

  • 使用ClassPathXmlApplicationContext创建IOC容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 使用FileSystemXmlApplicationContext创建容器
    此时,applicationContext.xml 的路径要写磁盘的物理路径
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("D:\\ideaworkspaces\\0919-spring\\01-spring\\src\\main\\resources\\applicationContext.xml");
  • 使用XmlWebApplicationContext创建容器
    使用XmlWebApplicationContext时要导入Tomcat,和spring-webmvc依赖
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.8.RELEASE</version>
</dependency>
 XmlWebApplicationContext context = new XmlWebApplicationContext();
        //设置配置文件位置
        context.setConfigLocation("classpath:applicationContext.xml");
        //调用refresh()方法
        context.refresh();
        HelloService helloService = context.getBean("helloService",HelloService.class);
        helloService.sayHello("李祥");

3.2.从IOC容器getBean的三种方法

  • 容器对象.getBean(“bean的id”),精确定位,需要强制转换
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = (HelloService) context.getBean("helloService");
helloService.sayHello("李祥");
  • 容器对象.getBean(“bean的id”,bean.class),精确定位,不需要强制转换
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = context.getBean("helloService",HelloService.class);
helloService.sayHello("李祥");
  • 容器对象.getBean(bean.class),不需要强制转换
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = context.getBean(HelloService.class);
helloService.sayHello("李祥");

3.3.Spring实例化bean的3种方法

  • 使用默认的构造方法创建bean对象

容器实例化会调用bean的默认无参数的构造方法,代码请看入门案例

  • 静态工厂方法创建bean对象
  • 创建工厂类HelloServiceFactory
public class HelloServiceFactory {
    public static HelloService helloServiceFactory(){  //注意是静态方法
        System.out.println("helloServiceFactory");
        return new HelloService();
    }
}
  • applicationContext.xml文件编写
 <bean id="helloServiceFactory" class="com.tjetc.factory.HelloServiceFactory" factory-method="helloServiceFactory">
 </bean>
  • 测试代码
ClassPathXmlApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = context.getBean(HelloService.class);
helloService.sayHello("李祥");
  • 实例工程方法创建bean
  • 创建工厂类HelloServiceFactory
public class HelloServiceFactory {
    public HelloService helloServiceFactory(){ //注意是非静态方法
        System.out.println("helloServiceFactory");
        return new HelloService();
    }
}
  • applicationContext.xml文件
<bean id="helloServiceFactory" class="com.tjetc.factory.HelloServiceFactory">
</bean>
<bean id="helloService" factory-bean="helloServiceFactory" factory-method="helloServiceFactory">
</bean>
  • 测试代码
ClassPathXmlApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml");
HelloService helloService = context.getBean(HelloService.class);
helloService.sayHello("李祥");

4.SpringIOC依赖注入

4.1.SpringIOC依赖注入简介

(1)SpringIOC的特点

  • Spring是轻量级容器+组件的管理模式
  • (2)什么是控制反转
  • 创建对象的权利由应程序创建改为由容器创建,控制权的转移称为控制反转.

(3)什么是依赖注入

  • 把容器创建好的依赖对象注入进来的过程称为依赖注入.
  • (4)依赖注入的目标
  • 提升组件重用的概率
  • 为系统搭建一个灵活、可扩展的平台

(5)Spring Framework的 IoC 容器操作基于两个包

org.springframework.beans 和 org.springframework.context

一个业务系统,由很多bean对象组成,bean之间存在调用关系,那么这些bean对象是如何协同工作的呢? 对象之间的调用,存在依赖关系,依赖对象的注入,称为依赖注入.


4.2.SpringIOC构造器注入

构造器注入bean子节点constructor-arg节点.可以使用constructor-arg节点属性index,name,type

基本类型注入:使用value

引用类型注入:使用ref

  • index构造方法参数的索引

准备一个实体类

public class Student {
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

applicationContext.xml中配置

<bean id="student" class = "com.tjetc.domain.Student">
    <constructor-arg index="0" value="张三"></constructor-arg> <!--构造器注入用constructor-arg-->
    <constructor-arg index="1" value="18"></constructor-arg>
</bean>

测试代码

public static void main(String[] args) {
    ClassPathXmlApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = context.getBean(Student.class);
    System.out.println(student);
    }
  • name构造方法的名称

实体类和测似代码不动,只要改变配置文件即可

<bean id="student" class = "com.tjetc.domain.Student">
    <constructor-arg name="name" value="张三"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
</bean>
  • type构造方法参数的类型

实体类和测似代码不动,只要改变配置文件即可

<bean id="student" class = "com.tjetc.domain.Student">
   <constructor-arg type="java.lang.String" value="张三"></constructor-arg>
    <constructor-arg type="int" value="16"></constructor-arg>
</bean>

注意如果是引用类型的bean用ref=“bean的id”

4.3.SpringIOC属性set方法注入

name是setXxx() 方法后单词的首字母变小写后的单词,不是属性名。

value代表的是值

ref代表的是引用类型的bean的id 的值

实体类中必须要有setter 、getter方法,以及无参构造

public Student() {
}
public Student(String name, int age) {
    this.name = name;
    this.age = age;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

applicationContext.xml配置文件

<bean id="student" class = "com.tjetc.domain.Student">
    <property name="name" value="张三"></property>
    <property name="age" value="13"></property>
</bean>

测试代码

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

set注入与构造器注入的对比

Set注入模式代码更加简洁

构造器注入对依赖关系的表达更加清楚

Set注入可以避免循环依赖问题

4.4.SpringIOC集合属性的注入

  • list、数组基本类型语法
<property name="hobbies">
      <list>
          <value>吃</value>
          <value>喝</value>
          <value>玩</value>
          <value>乐</value>
      </list>
</property>
  • list、数组引用类型语法
<property name="books">
     <list>
          <ref bean="book1"/>
          <ref bean="book2"/>
          <ref bean="book3"/>
     </list>
</property>
  • set基本数据类型语法
<property name="hobbies">
      <set>
           <value>吃</value>
           <value>喝</value>
           <value>玩</value>
           <value>乐</value>
           <value>读书</value>
      </set>
</property>
  • set引用数据类型语法
<property name="books">
     <set>
          <ref bean="book1"/>
          <ref bean="book2"/>
          <ref bean="book3"/>
     </set>
</property>
  • map基本类型语法
<property name="hobbies">
   <map>
    <entry key="chi" value="吃"></entry>
    <entry key="he" value="喝"></entry>
    <entry key="wan" value="完"></entry>
   </map>
</property>
  • map引用类型语法
<property name="books">
   <map>
     <entry key="xi" value-ref="book1"></entry>
     <entry key="dong" value-ref="book2"></entry>
     <entry key="nan" value-ref="book3"></entry>
   </map>
</property>
<property name="properties">
   <props>
       <prop key="pk1">pv1</prop>
       <prop key="pk2">pv2</prop>
       <prop key="pk3">pv3</prop>
       <prop key="pk4">pv4</prop>
   </props>
</property>

4.5.SpringIOC空间命名

(1)p空间命名

先要引入p空间命名

xmlns:p="http://www.springframework.org/schema/p"

基本数据类型

p:属性=值

<bean id="student" class = "com.tjetc.domain.Student" p:name="张三" p:age="12">
 </bean>


引用数据类型

p:属性-ref=另一个bean的id的值

<bean id="book" class="com.tjetc.domain.Book" p:name="西游记" p:price="30">
  </bean>
  <bean id="student" class="com.tjetc.domain.Student" p:name="张三" p:book-ref="book">
  </bean>

(2)c空间命名

先要引入c空间命名

xmlns:c="http://www.springframework.org/schema/c"

基本数据类型

c:构造方法参数名=值

<!--用属性名称注入-->
<bean id="student" class = "com.tjetc.domain.Student" c:name="张三" c:age="12">
</bean>
<!--用索引下标注入-->
<bean id="student" class = "com.tjetc.domain.Student" c:_0="张三" c:_1="12">
</bean>

引用数据类型

c:构造方法参数名-ref=另一个bean的id的值

<bean id="book" class="com.tjetc.domain.Book" p:name="西游记" p:price="30">
  </bean>
  <bean id="student" class="com.tjetc.domain.Student" c:name="李四" c:book-ref="book">
  </bean>

4.6.depends-on属性

B中没有A,在applicationContext.xml中配置depends-on=“a”,则先实例化A,再实例化B,销毁是先销毁B,再销毁A

依赖对象先创建后销毁.

public class Student {
    private String name;
    public Student() {
        System.out.println("Student()");
    }
    public void init(){
        System.out.println("Student.init()");
    }
    public void destroy(){
        System.out.println("Student.destroy()");
    }
}
public class MyClass {
    public String cname;
    public MyClass() {
        System.out.println("MyClass()");
    }
    public void init(){
        System.out.println("MyClass.init()");
    }
    public void destroy(){
        System.out.println("MyClass.destroy()");
    }
}

applicationContext.xml文件

 <bean id="student" class="com.tjetc.domain.Student" depends-on="myClass" init-method="init" destroy-method="destroy">
    </bean>
    <bean id="myClass" class="com.tjetc.domain.MyClass" init-method="init" destroy-method="destroy">
    </bean>

测试代码

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        context.close();

运行结果

MyClass() MyClass.init() Student() Student.init()

Student.destroy() MyClass.destroy()

4.7.延迟加载lazy-init

ApplicationContext的默认行为就是在创建IOC容器时将所有singleton 的bean提前进行实例化。

系统默认配置是lazy-init=“false”

当配置lazy-init="true"后,当第一次调用bean对象时,才进行实例

  • lazy-init="true"创建IOC容器时没有实例化bean,当第一次调用context.getBean(C.class)才进行实例化bean
<bean id="c" class="com.tjetc.domain.C" lazy-init="true"></bean>
  • lazy-init="true"只对当前的bean有效,对其他的bean不起作用
<bean id="c" class="com.tjetc.domain.C" lazy-init="true"></bean>
  <bean id="d" class="com.tjetc.domain.D"></bean>
  • beans节点设置 default-lazy-init=“true” ,让所有的bean都设置成懒加载.
<beans default-lazy-init="true" xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        ">
  <bean id="c" class="com.tjetc.domain.C"></bean>
  <bean id="d" class="com.tjetc.domain.D"></bean>
</beans>
  • default-lazy-init=“true” 所有bean懒加载的前提下,设置某个bean不懒加载 bean设置lazy-init=“false”
<bean id="d" class="com.tjetc.domain.D" lazy-init="false"></bean>


相关文章
|
1月前
|
XML 安全 Java
|
2月前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
55 0
|
2月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
10天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
5天前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
31 13
|
17天前
|
IDE Java 测试技术
互联网应用主流框架整合之Spring Boot开发
通过本文的介绍,我们详细探讨了Spring Boot开发的核心概念和实践方法,包括项目结构、数据访问层、服务层、控制层、配置管理、单元测试以及部署与运行。Spring Boot通过简化配置和强大的生态系统,使得互联网应用的开发更加高效和可靠。希望本文能够帮助开发者快速掌握Spring Boot,并在实际项目中灵活应用。
34 5
|
27天前
|
缓存 Java 数据库连接
Spring框架中的事件机制:深入理解与实践
Spring框架是一个广泛使用的Java企业级应用框架,提供了依赖注入、面向切面编程(AOP)、事务管理、Web应用程序开发等一系列功能。在Spring框架中,事件机制是一种重要的通信方式,它允许不同组件之间进行松耦合的通信,提高了应用程序的可维护性和可扩展性。本文将深入探讨Spring框架中的事件机制,包括不同类型的事件、底层原理、应用实践以及优缺点。
63 8
|
2月前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
81 6
|
2月前
|
Java 数据库连接 数据库
不可不知道的Spring 框架七大模块
Spring框架是一个全面的Java企业级应用开发框架,其核心容器模块为其他模块提供基础支持,包括Beans、Core、Context和SpEL四大子模块;数据访问及集成模块支持数据库操作,涵盖JDBC、ORM、OXM、JMS和Transactions;Web模块则专注于Web应用,提供Servlet、WebSocket等功能;此外,还包括AOP、Aspects、Instrumentation、Messaging和Test等辅助模块,共同构建强大的企业级应用解决方案。
104 2
|
3月前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
97 1
Spring 框架:Java 开发者的春天