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


相关文章
|
6天前
|
Java 数据安全/隐私保护 Spring
Java 中 Spring Boot 框架下的 Email 开发
Java 中 Spring Boot 框架下的 Email 开发
249 2
|
6天前
|
缓存 前端开发 Java
【框架】Spring 框架重点解析
【框架】Spring 框架重点解析
21 0
|
6天前
|
XML Java 数据格式
Spring框架入门:IoC与DI
【5月更文挑战第15天】本文介绍了Spring框架的核心特性——IoC(控制反转)和DI(依赖注入)。IoC通过将对象的创建和依赖关系管理交给容器,实现解耦。DI作为IoC的实现方式,允许外部注入依赖对象。文章讨论了过度依赖容器、配置复杂度等常见问题,并提出通过合理划分配置、使用注解简化管理等解决策略。同时,提醒开发者注意过度依赖注入和循环依赖,建议适度使用构造器注入和避免循环引用。通过代码示例展示了注解实现DI和配置类的使用。掌握IoC和DI能提升应用的灵活性和可维护性,实践中的反思和优化至关重要。
22 4
|
6天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
6天前
|
前端开发 Java 开发者
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
12 0
|
6天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(下)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
7 0
|
6天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(上)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
7 0
|
6天前
|
XML Java 应用服务中间件
【JavaEE】JavaEE进阶:框架的学习 - Spring的初步认识
【JavaEE】JavaEE进阶:框架的学习 - Spring的初步认识
10 0
|
6天前
|
Java 开发工具 Maven
根据SpringBoot Guides完成进行示例学习(详细步骤)
根据SpringBoot Guides完成进行示例学习(详细步骤)
9 1
|
6天前
|
XML Java 数据库连接
Spring框架与Spring Boot的区别和联系
Spring框架与Spring Boot的区别和联系
25 0