Spring(一)

Spring

简介

分层的Java SE/EE应用 full - stack轻量级开源框架。

核心:IOC(Inverse Of Control 控制反转)AOP(Aspect Oriented Programming 面向切面编程)

优势

  • 方便解耦,简化开发
  • AOP编程的支持
  • 声明式事务的支持
  • 方便程序的测试
  • 方便集成各种优秀框架
  • 降低JAVAEE API的使用难度
  • Java源码经典学习范例

体系结构

Spring的体系结构

1. Data Access/Integration(数据访问/集成)

数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。

  • JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
  • ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
  • OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
  • JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
  • Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。

2. Web 模块

Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。

  • Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
  • Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
  • Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
  • Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。

3. Core Container(核心容器)

Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。

  • Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
  • Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
  • Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
  • Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。

Spring程序开发步骤

image-20210727165139658

  1. 导入Spring开发的基本包坐标(Maven)
  2. 编写Dao接口和实现类
  3. 创建配置文件
  4. 在配置文件中配置实现类
  5. 使用Spring中API获取Bean实例

创建Maven项目

  1. 在pom.xml导入Spring开发的基本包坐标(导入坐标)

    <!--导入spring的context坐标,context依赖core、beans、expression-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
    
  2. 编写Dao接口和实现类

    image-20210728153640652
    public interface UserDao {
    
        public void save();
    }
    
    public class UserDaoImpl implements UserDao {
        public void save() {
            System.out.println("Hello");
        }
    }
    
  3. 在类路径下(resources)创建applocationContext.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">
    
         //配置对应userDao的实现类
        <bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
    </beans>
    
  4. 测试

    public class UserDaoDemo {
    
        public static void main(String[] args) {
            //创建ApplicationContext对象
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            //通过getBean方法获取配置文件中Bean(指定的对象)
            UserDao userDao = (UserDao) app.getBean("userDao");
            userDao.save();
        }
    }
    //结果:Hello
    

Spring配置文件

Bean标签基本配置

默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功

bean
  • 类型:标签·
  • 归属:beans标签
  • 作用:定义spring中的资源,受此标签定义的资源将受到spring控制
  • 格式:
<beans>
	<bean id="beanId" name="beanName1,beanName2" class="ClassName"></bean>
</beans>
  • 基本属性:
<bean id="beanId" name="beanName1,beanName2" class="ClassName"></bean>

/*
id:bean的名称,通过id值获取bean(对象),唯一性标识
class:Bean的全限定名称
name:bean的名称,可以通过name值获取bean,用于多人配合时给bean起别名
*/

Bean标签范围配置

scope
  • 类型:属性

  • 归属:bean标签

  • 作用:定义bean的作用范围

  • 格式:

        <bean id="userDao" class="dao.impl.UserDaoImpl" scope="singleton"></bean>
    
  • 取值:

    • singleton:

      实例化个数:1

      实例化时机:Spring容器被创建,加载配置文件时创建对象。

      **销毁:**应用卸载,销毁容器时

    • prototype:设定创建出的对象保存在spring容器中,

      实例化个数:多个

      实例化时机:在调用getBean方法时创建对象

      **销毁:**创建的对象长时间不用时(不可达判定二次标记),被GC回收了

    • request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置

Bean生命周期配置

init-method:

指定类中的初始化方法名称

destroy-method:

指定类中的销毁方法名称

  • 归属:bean标签

  • 作用:定义bean对象在初始化或销毁时完成的工作

  • 格式

        <bean id="userDao" class="dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
    
  • 注意事项:

    当scope=“singleton”时,spring容器中有且仅有一个对象,init方法在创建容器时仅执行一次

    当scope=“prototype”时,spring容器要创建同一类型的多个对象,init方法在每个对象创建时均执行一次

    当scope=“singleton”时,关闭容器会导致bean实例的销毁,调用destroy方法一次

    当scope=“prototype”时,对象的销毁由垃圾回收机制gc()控制,destroy方法将不会被执行

Bean实例化三种方式

  • 无参构造方法实例化(重要)

    <!--    无参构造创建对象--><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" </bean>
    
  • 工厂静态方法实例化(了解)

    /**
     * 定义工厂静态方法实例化
     */
    public class StaticFactory {
    
        public static UserDao getUserDao(){
            return new UserDaoImpl();
        }
    }
    
    <!--        工厂静态方法实例化配置-->
            <bean id="userDao" class="factory.StaticFactory" factory-method="getUserDao"></bean>
    
  • 工厂实例方法实例化(了解)

        //工厂实例方法实例化
        public  UserDao getUserDao1(){
            return new UserDaoImpl();
        }
    
    <!--    工厂实例方法实例化配置-->
    <!--    先获取StaticFactory对象-->
        <bean id="factory" class="factory.StaticFactory"></bean>
    <!--    再去调用实例方法实例化-->
        <bean id="userDao" factory-bean="factory" factory-method="getUserDao1"></bean>
    

Bean依赖的注入

image-20210728165623600

image-20210728165706555

依赖注入概念
  • DI(Dependency Injection)依赖注入,应用程序运行依赖的资源由Spring为其提供,资源进入应用程序的方式称为注入。Spring框架核心IOC的具体实现
  • 在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层(Service)仍会调用持久层(Dao)的方法。
  • 简单的说,就是坐等框架把持久层(Dao)对象传入业务层(Service),而不用我们自己去获取。
依赖注入方式
  • 构造方法
  • set方法
set方法注入
  • 名称:property

  • 类型:标签

  • 归属:bean标签

  • 作用:使用set方法的形式为bean提供资源

  • 格式:

    <bean>	<property /></bean>
    
<bean id="userDao" class="dao.impl.UserDaoImpl"></bean><bean id="userService" class="service.impl.UserServiceImpl">    <!--    set方法注入 -->    <!--       name对应set方法,例如 setUserDao方法去掉set,之后首字母小写-userDao-->    <!--        ref 将bean 中 id为userDao引入-->    <property name="userDao" ref="userDao" ></property></bean>

name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)

value:设定非引用类型属性对应的值,不能与ref同时使用

ref:设定引用类型属性对应bean的id ,不能与value同时使用

使用p命名空间简化配置(了解)

使用p命令空间需要先开启spring对p命令空间的的支持,在beans标签中添加对应空间支持

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

例子

<bean id="userService" class="service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

和上面使用property相对比,变得简介了。

构造方式注入
  • 名称:constructor-arg

  • 类型:标签

  • 归属:bean标签

  • 作用:使用构造方法的形式为bean提供资源,兼容早期遗留系统的升级工作

  • 格式:

    <bean>	<constructor-arg /></bean>
    

例子

<!--    构造方法注入-->    <bean id="userService" class="service.impl.UserServiceImpl"><!--        name指的是构造函数中的参数名userDao--><!--        public UserServiceImpl(UserDao userDao) {--><!--        this.userDao = userDao;--><!--        }--><!--        ref指bean 中 id为userDao引入-->        <constructor-arg name="userDao" ref="userDao"></constructor-arg>    </bean>

name:对应bean中的构造方法所携带的参数名

ref:设定**引用类型(对象)**构造方法参数对应bean的id ,不能与value同时使用

<constructor-arg index="arg-index" type="arg-type" ref="beanId" value=""/>

value:设定**非引用类型(基本数据类型)**构造方法参数对应的值,不能与ref同时使用

type :设定构造方法参数的类型,用于按类型匹配参数或进行类型校验

index :设定构造方法参数的位置,用于按位置匹配参数,参数index值从0开始计数

注意:一个bean可以有多个constructor-arg标签

依赖注入数据类型

之前都是对象数据的引入,接下来介绍基本数据类型的引用

对于集合数据类型注入:

  • 名称:array,list,set,map,props

  • 归属:property标签 或 constructor-arg标签

  • 作用:注入集合数据类型属性

  • 普通数据注入

public class User {

    private String name ;
    private int 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;
    }

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

对应xml文件中的配置

    <bean id="user" class="entity.User">
     <!--        name是属性名,也就是setUsername方法去掉set,之后首字母小写-->
     <!--        name是属性名,也就是setAge方法去掉set,之后首字母小写-->
     <!--        普通值的注入,用value-->
        <property name="name" value="汤姆猫"></property>
        <property name="age" value="12"></property>
    </bean>
    <bean id="user1" class="entity.User">
        <property name="name" value="杰瑞"></property>
        <property name="age" value="8"></property>
    </bean>
  • List类型注入
//集合
    private List<String> strList;
    public void setStrList(List<String> strList) {
        this.strList = strList;
    }

对应xml文件中的配置

    <bean id="baseDataDao" class="dao.impl.BaseDataImpl">
        <property name="strList">
<!--            list类型-->
            <list>
<!--                value对应非引用数据类型,ref对应引用数据类型-->
                <value>赵信</value>
                <value>卡莎</value>
                <value>薇恩</value>
            </list>
        </property>
     </bean>

  • Map类型注入
    private Map<String, User> userMap;    public void setUserMap(Map<String, User> userMap) {        this.userMap = userMap;    }

对应xml文件中的配置

    <bean id="baseDataDao" class="dao.impl.BaseDataImpl">        <property name="userMap">            <!--        map类型-->            <map>                <entry key="key1" value-ref="user"></entry>                <entry key="key2" value-ref="user1"></entry>            </map>        </property>     </bean>
  • Properties注入
    private Properties properties;    public void setProperties(Properties properties) {        this.properties = properties;    }

对应xml文件中的配置

    <bean id="baseDataDao" class="dao.impl.BaseDataImpl">        <property name="properties">            <props>                <prop key="p1">北京</prop>                <prop key="p2">南京</prop>            </props>        </property>     </bean>
团队开发

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

  • 类型:标签

  • 归属:beans标签

  • 作用:在当前配置文件中导入其他配置文件中的项

  • 格式:

    <beans>    <import /></beans>
    
  • 基本属性:

    <import resource=“config.xml"/>
    

resource:加载的配置文件名

  • Spring容器加载多个配置文件

    new ClassPathXmlApplicationContext("config1.xml","config2.xml");
    
  • Spring容器中的bean定义冲突问题

    • 同id的bean,后定义的覆盖先定义的
    • 导入配置文件可以理解为将导入的配置文件复制粘贴到对应位置
    • 导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同

Spring相关API

applicationContext接口

applicationContext :接口类型,代表应用上下文,可以通过其实例获得Spring容器中的Bean对象

applicationContext实现类

ClassPathXmlApplicationContext : 它是从类的根路径下加载配置文件,推荐使用这种

FileSystemXmlApplicationContext : 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置

AnnotationConfigApplicationContext : 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解

getBean()方法

getBean(“id”) : 当参数的数据类型是字符串时,表示根据 Bean 的 id 从容器中获得Bean实例,返回是Object,需要强转。

getBean(Class) :当参数的数据类型是Class字节码类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,

则此方法会报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值