详解spring框架入门到精通


Spring框架轻量级一站式框架。 提供了两个核心 IOCAOP
轻量:
一站式: spring在三层架构都提供了相应的解决方案。
Dao: JdbcTemplate模板对象,简化jdbc开发。 (DbUtils框架)
Service: 提供了声明式事务的管理操作。
Web: springmvc 框架:

spring框架的优点

Spring框架的出现, 使得javaEE开发更加简单。
面向接口开发, 不是针对类。 更加利于扩展和维护。
能够使得程序耦合度降低(松耦合)
Spring能够整合外部优秀的框架。
Spring当中整合了单元测试, 测试更加方便。
Spring当中提供了声明式事务。 配置就可以解决事务~


任何javaEE程序都可以从spring当中受益 。

spring框架的组成

在这里插入图片描述
架的基本组成。 spring框架运行, 必须依赖core。

Aop 模块相关: 面向切面编程~
Web: 在web层提供了相应的技术: springmvc servlet
Data access: jdbc ORM:(整合外部的优秀框架, Mybatis,Hibernate) Transactions
Test: 整合了junit单元测试:

spring核心IOC

IOC概述

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
创建对象的权利翻转交给spring框架完成。 对象放在一个IOC容器当中, 需要使用的时候从容器当中获得一个就OK。 该过程就是一个控制翻转的过程。

传统
Dao: service: web: 层层之间依赖关系(UserService层当中出现了Dao代码): 不利于扩展, 不利于维护。
Service

Public class UserService{
   UserDao dao = new UserDaoImpl();
}

Spring: ioc 就可以解决上述问题。 耦合度高的问题。
我们需要使用对象的时候, 不用直接new 关键字创建。从容器当中获得一个对象。

IOC入门案例

搭建spring环境。
(1)创建工程: maven jar
(2)引入spring的相关依赖:
(3)引入spring核心配置文件: 名称可以任意: applicationContext.xml spring_xxx.xml
(4)IOC: 配置
(5)测试

创建maven jar工程

springDemo

引入spring的依赖

在这里插入图片描述

引入spring的核心配置文件applicationContext.xml

从官网copy: xml的头信息~
spring官网:https://spring.io/
Spring的文档地址::https://docs.spring.io/spring-framework/docs/5.2.10.RELEASE/spring-framework-reference/core.html#spring-core

<?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-->
    <bean id="car" class="com.offcn.pojo.Car"/>

</beans>

测试

@Test
public void shouldAnswerWithTrue()
{
  //读取配置文件:  创建了IOC容器:容器当中保存了配置文件当中配置的bean对象: 
    ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext("applicationContext.xml");
   
    //从容器当中根据id获取对象: 
    Car car = (Car) context.getBean("car");
    System.out.println(car);
    // 容器关闭: 
    context.close();
}

IOC容器对象的方法补充

@Test
public void test1()
{
    //读取配置文件:  创建了IOC容器:容器当中保存了配置文件当中配置的bean对象:
    ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext("applicationContext.xml");

    //从容器当中根据id获取对象:
    Person person = (Person) context.getBean("person");
    System.out.println(person);

    //根据类型从容器当中查询:
    Person bean = context.getBean(Person.class);
    System.out.println(bean);
    System.out.println("xxxxx");
    String[] names = context.getBeanDefinitionNames();
    System.out.println(Arrays.toString(names));// [car, person]

    //Map<id,Person>
    Map<String, Person> beansOfType = context.getBeansOfType(Person.class);
    System.out.println(beansOfType);


    // 容器关闭:
    context.close();
}

DI 依赖注入

setter注入:

<!--管理bean-->
<bean id="car" class="com.offcn.pojo.Car">
  <!--setter注入:-->
    <property name="name" value="兰博基尼"/>
    <property name="color" value="蓝色"/>
    <property name="price" value="3000000"/>

</bean>

<!--bean配置person-->
<bean id="person" class="com.offcn.pojo.Person" >
    <!--
       setter注入: 
       (1)实体类当中必须存在setter方法: 
       (2)注入的是一个普通属性: value值: 
       (3)注入的是一个对象属性: ref
    -->
    <property name="username" value="鹏程"/>
    <property name="age" value="30"/>
    <property name="car" ref="car"/>
</bean>

构造器注入

<!--管理bean-->
<bean id="car" class="com.offcn.pojo.Car">

    <!--构造器注入:提供对应的构造器:  -->
    <constructor-arg name="name" value="迈巴赫"/>
    <constructor-arg name="color" value="黑色"/>
    <constructor-arg name="price" value="1200000"/>

</bean>

<!--bean配置person-->
<bean id="person" class="com.offcn.pojo.Person" >
   
    <!--构造器注入: -->
    <constructor-arg name="username" value="王磊"/>
    <constructor-arg name="age" value="30"/>
    <constructor-arg name="car" ref="car"/>
</bean>

总结: setter注入, 构造器注入就是常用的注入方式。

名称空间注入

P名空间在spring2.0 引入: 我们使用的版本肯定支持。
步骤一: 引入p名称空间 xmlns:p=“http://www.springframework.org/schema/p”

步骤二: 使用P名称空间:
P:属性名称= value;

<!--管理bean-->
<bean id="car" class="com.offcn.pojo.Car"
      p:name="大奔" p:color="黑色" p:price="1000000">
  </bean>

<!--bean配置person-->
<bean id="person" class="com.offcn.pojo.Person" p:username="杨文斌" p:age="20" p:car-ref="car" >
    </bean>

SPEL注入:

SpEl 注入使用了spring 框架提供的spring el表达式进行注入。 功能最强大。
Value的值可以是简单类型的值: 可以是方法调用之后获得值。 可以是从配置文件当中获得值。

Spring3.0 版本提供的新特性。

<!--管理bean-->
<bean id="car" class="com.offcn.pojo.Car">
  
    <!--SpEl注入: 功能最强大 : springEL
        #{}
        #{''}
        #{数值元素}
        #{方法调用}
        如果注入的是一个对象类型, 属性依然使用value属性
   -->
    <property name="name" value="#{'wangzong'}"/>
    <property name="color" value="#{car.getColor()}"/>
    <property name="price" value="#{3000000+1}"/>


</bean>

<!--bean配置person-->
<bean id="person" class="com.offcn.pojo.Person" >
   
    <property name="username" value="#{'mrzhang'}"/>
    <property name="age" value="18"/>
    <!--引入的一个对象类型, 依然使用value属性: -->
    <property name="car" value="#{car}"/>

</bean>

DI注入集合类型

注入数组类型

<bean id="user" class="com.offcn.pojo.User">
    <property name="id" value="1001"/>
    <property name="name" value="张万伟"/>
    <property name="names" >
        <array>
            <value>张三丰</value>
            <value>老张</value>
            <value>张同志</value>
            <value>狗蛋</value>
        </array>
    </property>
</bean>

注入List集合类型:

<!--注入list集合: -->
    <property name="hobbies" >
        <list>
            <value> 学习java </value>
            <value> 学习Mybatis </value>
            <value> 学习spring </value>
        </list>
    </property>

注入set集合类型

<property name="address">
    <set>
        <value>深圳 </value>
        <value>北京</value>
        <value>上海</value>
    </set>
</property>

注入Map集合类型

 
<!--map集合:-->
<property name="car" >
    <map>
        <entry key="car1" value-ref="car"></entry>
        <entry key="car2" value-ref="car2"></entry>
    </map>
</property>

Properties集合类型

Properties集合: 是一个特殊的map集合: 集合的key 和value都是String类型。 所以不需要指定key 和value。
属性表集合: 因为一般该集合结合外部的xxx.properties文件使用。
xxx.properties文件: 制定key 和value: jdbc.username=root

<!--注入properties集合对象: -->
<property name="prop">
    <props>
        <prop key="names1">女对象1</prop>
        <prop key="names2">女对象2</prop>
        <prop key="names3">女对象3</prop>
    </props>
</property>

说明
List集合的底层数据结构: HashMap HashSet

bean实例化方式-三种方式

调用了无参数构造器

默认调用无参数构造器, 对象进行创建。
前提: bean必须提供无参数构造器。

/ new Book();
// 反射: 全限定类型
public Book(){
    System.out.println("无参数构造器被执行了.....");
}

静态工厂

静态工厂, 工厂当中提供的方法都是静态方法。 这样的工厂静态工厂。

创建静态工厂的实体类:

public class StaticFactory {


    /**
     * 静态方法: 随着类的加载而加载。
     *
     * @return Object对象:
     */
    public static Book getInstance(){
        System.out.println("static faactory static Method.....");
        return new Book();
    }
}

配置

<!--静态工厂方式: 生产对象
    核心配置文件被读取的时候, 静态工厂当中的静态方法被执行了。 
    静态方法的返回值存放在IOC容器当中。 
    class: 指定的静态工厂实例类: 
    factory-method:静态工厂的静态方法: 
-->
<bean id="book2" class="com.offcn.pojo.StaticFactory" factory-method="getInstance"/>

实例工厂

创建工厂类

public class InstanceFactory {

    /**
     * 创建了一个实例方法:
     * @return
     */
    public Book getInstance(){
        System.out.println("instance factory method execute....");
        return  new Book();
    }
}

配置

<!--将实例工厂交给spring管理
  实例工厂: 
  (1)创建实例工厂: 
  (2)实例工厂创建对象: 
  factory-bean:指定工厂类
  factory-method:指定工厂类的工厂方法。 
-->
<bean id="factory" class="com.offcn.pojo.InstanceFactory"/>
<bean id="book3" factory-bean="factory" factory-method="getInstance"></bean>

bean对象初始化相关

生命周期相关的两个方法

创建了实体类当中相关方法

@Data
public class Book implements Serializable {
    private String name;
    private double price;
    private String auth;


    // new Book();
    // 反射: 全限定类型
    public Book() {
        System.out.println("无参数构造器被执行了.....");
    }


    public void init() {
        //方法能够对创建出来的对象进行一个初始化 : 对象----》初始化。
        System.out.println("book 对象初始化操作。。。。。。。");
    }

    public void destroy(){
        System.out.println("book 对象销毁之前调用......");
    }

}

配置

<!--spring管理book对象:
  init-method="init" 指定了对象的初始化方法。 在对象创建之后执行init方法。
  destroy-method="destroy" 指定了对象的销毁方法。 在对象销毁之前调用。 
                     只有当工厂关闭的时候,destroy 方法才会被调用。 
 -->
<bean id="book" class="com.offcn.pojo.Book" init-method="init" destroy-method="destroy" >
    <property name="price" value="29.9"/>
    <property name="name" value="疯狂java"/>
    <property name="auth" value="李刚"/>
</bean>

bean 作用范围

作用域 描述
singleton 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。

spring容器在创建对象的时机

当IOC容器创建,(工厂)时候, 指定了applicationContext.xml核心配置文件。 配置文件当中配置的bean 都会被创建存放在IOC容器当中。 spring IOC容器默认是单例形式创建对象。

多例模式创建对象

<!--spring管理book对象:
  init-method="init" 指定了对象的初始化方法。 在对象创建之后执行init方法。
  destroy-method="destroy" 指定了对象的销毁方法。 在对象销毁之前调用。
                     只有当工厂关闭的时候,destroy 方法才会被调用。
  scope="singleton" : 默认值: 单例形式创建对象。

         prototype:  多例的模式创建。     spring 整合Struts2 的时候,  多例~
 -->
<bean id="book" class="com.offcn.pojo.Book" init-method="init"
      destroy-method="destroy" scope="prototype" >
    <property name="price" value="29.9"/>
    <property name="name" value="疯狂java"/>
    <property name="auth" value="李刚"/>
</bean>                

如果指定了scope属性为 prototype, 对象多例模式创建。
创建时机: 当从容器当中获得对象的时候, bean对象才会被创建。
创建: 多例模式创建。 每调用一次就会创建一个新的对象。
销毁: 工厂关闭的时候, destroy方法不会调用。 destroy方法只针对单例模式。
总结:实际开发当中一般情况都使用默认单例模式。 spring整合Struts2
的时候使用多例。

scope 属性(面试题目)

默认值: singleton 单例模式创建。
Prototype: 多例模式创建。
Request: 依赖web环境。 创建出来的对象会存在Request当中一份。
Session: 依赖web环境。 创建的对象会存放在session域当中一份。
globalSession: 应用在分布式集群环境当中。 创建的对象存在全局的session当中。

对象的详解

工厂的继承体系图

在这里插入图片描述

常用工厂对象的详解

BeanFactory对象:接口类型, 工厂对象, 是一个顶层对象。 一般不直接使用, 留给Spring框架设计者使用。

ApplicationContext 接口: BeanFactory子接口。 该接口提供了更加丰富的功能。 程序员一般使用该接口:

FileSystemXmlApplicationContext: 类, 父接口ApplicationContext 。能够读取文件系统当中的配置文件。

ClassPathXmlApplicationContext : 能够读取类路径下的资源。 类路径~(classes)

BeanFactory和ApplicationContext 区别(面试题目)

BeanFactory主要是面向Spring框架的基础设施,也就是供spring自身内部调用, 而Applicationcontext 主要面向Spring的使用者。
BeanFactroy在第一次使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化, 而ApplicationContext是在容器启动时,一次性创建并加载了所有的Bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值