Java 之 Spring 框架概述

Spring

Spring是一个开放源代码的设计层面框架
他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。
简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
把它理解为对象的管家,帮忙管理项目中用到的对象
其实说白了就是容器

特点

1.开源
2.轻量级(体积小)
3.分层架构(按需添加)
4.一站式(对目前流行的框架支持非常高)
5.IOC
6.DI
使用 Spring 带来的好处
1.降低复杂性
2.松耦合
3.高性能
4.易测试 Junit
5.声明式事务

创建 Spring 流程

1.下载所需 jar 包
2.导入核心包 beans context expression core logging(日志包)
3.创建编写配置文件
    创建对象交给 Spring 来管理
4.创建 applicationContex容器
5.通过 getBean 来获取到对象,如果对象不为空,则 Spring 搭建成功
public class HelloSpring {
    public static void main(String[] args) {
        // 从容器中获取被管理的对象
        // 1.创建容器
        // ClassPathXmlApplicationContext("classpath:applicationContext.xml"); 
        // 使用指定配置文件,classpath 可忽略不写
        @SuppressWarnings("resource")
        ApplicationContext applicationContext = new 
        ClassPathXmlApplicationContext("applicationContext.xml");
        // 2.从容器中获取 bean
        Person person = (Person) applicationContext.getBean("person");
        // 查看对象是否获取成功
        System.out.println(person);
    }
}


<?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">

    <!-- 让 Spring 管理 Person 的对象,对象名字叫做 person
        class:全限定类名,要被管理的类的名字
        name:被管理对象的名称
     -->
    <bean class="com.xxx.Person" name="person">
        <!-- set 注入
            必须提供 set 方法
            value 属性用于注入基础数据类型
            ref 属性用于注入引用数据类型
             -->
        <property name="name" value="张三"></property>
        <property name="age" value="20"></property>
        <property name="car" ref="car"></property>
    </bean>
    <bean class="com.xxx.Car" name="car">
        <property name="name" value="布加迪威龙"></property>
        <property name="color" value="鎏金"></property>
    </bean>
</beans>

核心思想 IOC

inverse of control(反转控制)
说白了就是把对象的创建反转(交给) Spring 来管理
不需要手动去创建对象,需要调用时,从 Spring 获取对象
实现原理:通过反射 + 配置文件
Class class = Class.forName("com.xxx.Person");
Object object = class.newIncetance();
context.put("person", object);

context.get("person");

DI技术

dependency injection
   依赖         注入
类 A 中需要类 B 提供的功能
称为 A 依赖 B
例如: service 依赖 DAO
UserService
UserDao dao = new UserDaoImplForJDBC();
UserDao dao = new UserDaoImplForHibernate();
使用 Spring 之后 
UserDao dao = context.getBean("userDaoImpl");
不需要修改源代码就能实现组件的切换

注入:从外部把需要的对象放到内部就叫注入
UserService
private UserDao dao;
set/get 方法

依赖注入最终的目的就是提高程序的扩展性,尽可能的不去修改源代码

bean 的创建方式

1.构造函数创建(默认的)
<bean name="person4" class="com.lanou3g.Person">
    <!-- name 指定参数名,需要与构造函数一致 -->
    <!-- index 指定参数放到哪一个位置
        使用场景:当多个构造函数参数相同,但是顺序不同时,调用 -->
    <!-- type 指定参数的类型
        使用场景:当多个构造函数参数顺序相同,但是数据类型不同时,调用 -->
    <constructor-arg name="car" ref="car" index="0"></constructor-arg>
    <constructor-arg name="name" value="0123" type="Integer"></constructor-arg>
    <constructor-arg name="age" value="20"></constructor-arg>
</bean>
2.静态工厂创建(调用指定的静态方法获取 bean)
<!-- 到 PersonFactory 中调用 getPerson 的静态方法来获取对象,并放入容器中
    如果使用默认的创建方式, Spring 会到对应类中找到空参数的构造函数
    如果指定了 factory-method, 则 Spring 会到类中找到指定的静态方法执行
    class 指定类型可以与 bean 的类型不一致
 -->
<bean name="person2" class="com.xxx.PersonFactory"  factory-method="getPerson">
    <property name="name" value="王五"></property>
</bean>
3.实例工厂创建(调用实例方法获取 bean)
<!-- 通过实例工厂方法创建
    到 PersonFactory 的某个对象中找到 getPerson2的方法,获取返回对象
 -->
<bean name="personFactory" class="com.lanou3g.PersonFactory"></bean>
<bean name="person3" class="com.lanou3g.PersonFactory" 
    factory-method="getPerson2" factory-bean="personFactory">
    <property name="name" value="赵六"></property>
</bean>

依赖注入的四种方式

1.set 注入(就是通过 set 方法,所以必须有 set 方法)
<bean class="com.lanou3g.Person" name="person">
    <!-- set 注入
        必须提供 set 方法
        value 属性用于注入基础数据类型
        ref 属性用于注入引用数据类型
         -->
    <property name="name" value="张三"></property>
    <property name="age" value="20"></property>
    <property name="car" ref="car"></property>
</bean>
<bean class="com.lanou3g.Car" name="car">
    <property name="name" value="布加迪威龙"></property>
    <property name="color" value="鎏金"></property>
</bean>
2.构造函数注入
<bean name="person4" class="com.lanou3g.Person">
    <!-- name 指定参数名,需要与构造函数一致 -->
    <!-- index 指定参数放到哪一个位置
        使用场景:当多个构造函数参数相同,但是顺序不同时,调用 -->
    <!-- type 指定参数的类型
        使用场景:当多个构造函数参数顺序相同,但是数据类型不同时,调用 -->
    <constructor-arg name="car" ref="car" index="0"></constructor-arg>
    <constructor-arg name="name" value="0123" type="Integer"></constructor-arg>
    <constructor-arg name="age" value="20"></constructor-arg>
</bean>
3.<:p 命名空间
<?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"
    xmlns:p="http://www.springframework.org/schema/p"><!-- p 命名空间需要先引入命名空间 -->

<!-- p 命名空间
        实质上还是调用 set 方法,只是为了简化书写 -->
    <bean name="person5" class="com.lanou3g.Person" p:name="老王" p:age="50" p:car-ref="car"></bean>
4.SpEL 表达式
<!-- SpEL 注入
    Spring 的表达式语言,能够实现一些简单的逻辑
    与 JSP 的 EL 一个性质 -->
<bean name="person6" class="com.lanou3g.Person">
    <!-- 找到一个叫 person 的对象,调用 getName 方法获取数据 -->
    <property name="name" value="#{person.name}"></property>
    <property name="age" value="#{person5.age}"></property>
    <property name="car" ref="car"></property>
</bean>

ApplicationContext 的两个实现类

ClassPathXMLApplicationContext 用于加载 Class 路径下的配置文件
FileSystemXMLApplicationContext 用于加载系统路径下的配置文件

public class HelloSpring {
    public static void main(String[] args) {
        // ApplicationContext 接口有两个实现类

        // 从类路径下加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        System.out.println(applicationContext.getBean("person"));
        // 从系统路径下加载配置文件
        ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("file:/Users/eclipse-workspace/spring/src/beans.xml");
        System.out.println(applicationContext2.getBean("person"));
    }
}

两种容器

Spring 提供两种容器 
1.BeanFactory(已经过时了) Spring 框架最古老的接口 
仅定义了实现 IOC DI 基础功能的接口
特点:获取 bean 时才会创建对应 bean 以前的硬件设备资源匮乏 
2.ApplicationContext 功能更加强大
特点:一旦加载配置文件就全部创建出来

bean 元素的属性

scope
    singleton   单例(默认)
    prototype   多例
    requestrequest 生命周期一致
    session     与 session 生命周期一致

scope 属性用来指定 bean 的作用域
        singleton: 单例,该 bean 对象在 Spring 中只存在一个 *最常用
        (注意:在和 struts2整合时,Action 对象不能设置为单例)
        prototype: 多例,每次 getBean 是都会创建新的 bean *
        request 和 session 对象的生存时间与 session 或 request 一致

生命周期方法

init-method     对象创建完立即执行
destroy-method  对象销毁前执行
idname 功能是一样的
id 不能重复,不能用特殊字符
name 可以重复,可以有特殊字符

复杂类型的注入

array       使用 array 子标签
            例如:<array>
                    <value>123</value>
                </array>
list        使用 list 子标签(同 array)
            例如:<list>
                    <value>456</value>
                </list>
map         使用 entry 子标签
            例如:<map>
                    <entry key="name" value="qaz1"></entry>
                    <entry key="age" value="10"></entry>
                    <entry key-ref="引用类型" value="这是一个 bean"></entry>
                    <entry key="这是一个 bean" value-ref="引用类型"></entry>
                </map>
properties  使用 props 子标签
            例如:<props>
                    <prop key="jdbcDriver">jdbc:mysql://localhost:3306/MyDB</prop>
                    <prop key="user">root</prop>
                    <prop key="password">123456</prop>
                </props>
<bean id="collectionBean" class="com.lanou3g.CollectionBean">
    <!-- 元素只有一个值,可以直接使用 value 注入 -->
    <property name="array">
        <array>
            <value>jack</value>
            <value>rose</value>
            <value>john</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>1</value>
            <value>2</value>
            <value>3</value>
        </list>
    </property>
    <!-- 元素只有一个时,也不能用 value 注入 -->
    <property name="map">
        <map>
            <!-- 使用 entry 标签来指定键值对 -->
            <entry key="name" value="qaz1"></entry>
            <entry key="age" value="10"></entry>
            <entry key-ref="abean" value="这是一个 bean"></entry>
            <entry key="这是一个 bean" value-ref="abean"></entry>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="jdbcDriver">jdbc:mysql://localhost:3306/MyDB</prop>
            <prop key="user">root</prop>
            <prop key="password">123456</prop>
        </props>
    </property>
</bean> 
<bean name="abean" class="com.lanou3g.CollectionBean"></bean>

配置文件的模块化

当一个配置文件内容太多时,可以按照功能模块划分
1.在创建容器时,传入多个字符串对象(配置文件名)
ApplicationContext applicationContext 
= new ClassPathXmlApplicationContext("beans.xml", "applicationContext.xml");
2.在一个配置文件中使用 import 标签导入其他配置文件
<import resource="classpath:applicationContext.xml"/>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值