Spring day01

  1. 概述
    Spring是全栈型(full - stack)的 轻量级开源框架他能整合许多“开源”的第三方架构。 使其逐渐成为使用最多的Java EE企业应用开源架构。 以IOC (Inverse- of -Control) 控制反转,AOP 面向切面编程 为内核。
  • Spring 的优势

    • 方便解耦,简化开发
    • AOP编程 (面向切面编程) 的支持
    • 声明式事务的支持
    • 方便程序的测试
    • 方便集成各种优秀框架
    • 源码特别的经典,设计巧妙、结构清晰
  • Spring的体系结构

    • Core Container :核心容器。 是Spring的 IOC部分Spring 框架任何其他部分的运行都必须 要有核心容器的支持
  1. 程序的耦合 :程序间的依赖关系,我们只能降低不能没有。
    • 耦合:
      程序间的依赖关系
      类之间的依赖关系
    • 解耦:使用工厂模式
      降低程序间的依赖关系
      (1):使用反射技术创建对象,而不是使用new 关键字。 这样类的依赖就是 一个“字符串”了
      (2):通过配置文件(properties,xml)的方式来 获取要创建的对象全限定类名。

案例说明: 程序的耦合。
  表现层 new创建一个业务层接口实体类,该业务实体类中有个持久层接口实体类(对象映射关系)对象。业务层的saveAccount方法中是持久层实体类调用 saveAccount方法打印表示 创建账户成功。
  表现层调用业务层,业务层调用持久层。 其中的调用就是类与类的嵌套。 如下:

//业务层调用持久层,所以需要 来IAccountDao
    private IAccountDao accountDao=new AccountDaoImpl();
    public void saveAccount() {

        accountDao.saveAccount();
        //getResourceAsStream():这个方法是获取资源目录下的文件输入流。   建议使用类加载器去获取。
    }

  从上面的例子可以看出类与类之间的耦合(依赖关系)是非常严重的。 表现层调用业务层,业务层内部new创建持久层,并调用方法打印输出提示成功。
  解决: 工厂模式解耦。自定义一个工具类 根据传入的全限定类名来返回不同的对象。
   工厂模式改善: 由于我们是直接创建的 业务层对象与持久层接口对象。并没有保存 所以每当 表现层调用业务层时都是一个新的对象。 这样开发的效率并不是很高。
    解决: 工厂类定义一个容器存放创建的对象。 一个全限定类名只有一个对象也就是单列对象。

  1. IOC
    概念: 通过上面的案例说明,可以发现我们 使用了一个 “工厂对象” 来获取想要的接口实体类。并使其一个全限定类名永远只返回一个对象。 其实这就是 控制反转(IOC):将创建对象的权力交给框架。
    作用: 削减程序的依赖。 但是肯定无法没有依赖。

4.Spring的IOC    Spring框架的核心之一。 使用工厂模式解耦,降低程序间的依赖。
   使用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">


    <!--把对象的创建交给Spring架构来管理-->
    <!--id :唯一标识符。  核心容器通过 id来返回对象。			SpringIOC控制反转:创建对象交给Spring架构,是Spring的核心之一。
    ,class:实体类  的全限定类名,也可以是jar包里面的class文件。		通过反射技术生产对象,降低程序间的 耦合度。-->
    
    <bean id="AccountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
    
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
    <!--综上所述:就是上面介绍的工厂模式的体现-->
</beans>

  
  通过核心容器获取对象 如下:

//获取核心容器 (是一个接口,有三个实现类。) 对象,  并直定配置文件方便读取配置信息。
ApplicationContext ac= new ClassPathXmlApplicationContext("bean.xml");
//通过核心容器对象获取 对象。		
IAccountService as= (IAccountService) ac.getBean("AccountService");
IAccountDao adao=ac.getBean("accountDao", AccountDaoImpl.class);
System.out.println(as);
System.out.println(adao);

   核心容器接口(ApplicationContext)的实现类区别:
      (1):ClassPathXmlApplicationContext,他可以加载类路径下的配置文件。 要求配置文件必须在类路径下。
      (2):FileSystemXmlApplicationContext,它可以加载磁盘路径下的配置文件。 要求必须要有访问权限。
      (3):AnnotationConfigApplicationContext, 读取注解的方式创建核心容器对象。

 //立即加载。  只要下面的核心容器接口对象一旦被创建,xml里面的bean标签 指定的类、jar包中的class文件 都会马上创建一个对象  								存放到核心容器中,无论怎样获取都是哪一个对象。
 //如果bean标签指定的 内容重复,则创建多个实体类对象。
 ApplicationContext ac= new ClassPathXmlApplicationContext("bean.xml");
 
 ApplicationContext ac=new FileSystemXmlApplicationContext("D:\\idea_\\project\\day01_eesy_03spring\\src\\main\\resources\\bean.xml");
       

   第一种方式更贴切实际开发


    配置文件使用bean 标签创建对象的三种方式
    指定该xml核心容器一经创建 则bean标签指定的实体类就会被创建并存放至核心容器中

<!--把对象的创建交给Spring架构来管理-->
    <!--id :唯一标识符,class:实体类的全限定类名,也可以是jar包中的class文件-->

    <!--第一种:默认构造函数创建对象,并存放到核心容器中,如果实体类没有构造函数则对象无法创建。-->
    <bean id="AccountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>

    <!--第二种:使用工厂的方法获取对象(使用某个类的方法创建对象,并返回创建的对象)。并存放到核心容器中
    具体方法里面是怎么创建的对象 应该有参构造可以,无参构造也可以。这样就解决了只能使用
    默认构造方法创建对象。-->
    <bean id="beanFactory" class="com.itheima.factory.InstanceFactory"></bean>
    <bean id="AccountService______2" factory-bean="beanFactory" factory-method="getAccoutnService"></bean>

    <!--第三种:使用工厂的静态方法获取对象(使用某个类的静态方法创建对象,并返回创建的对象)存入容器中。 直接将第二种压缩至一行-->
    <bean id="AccountService_______3" class="com.itheima.factory.StaticFactory" factory-method="getAccoutnService"></bean>


    配置文件使用bean 标签的作用范围

<!--bean的作用范围调整
        Scope属性:
            singleton:单例的(默认值)
            prototype:多列的
            request:作用于web应用的请求范围
            session:作用于web应用的会话范围
            global-session:作用于集群环境的会话范围,如果不是集群环境,那就是session-->


    global-session图解在这里插入图片描述


    配置文件使用bean 标签 指定的实体类或者class文件 他们的对象生命周期

<!--bean的生命周期:
        单例对象:singleton,每次从核心容器获取对象都是一样的对象。       采用立即加载
            出生:     读取配置文件完成时,创建对象。
            活着:     核心容器存在,对象就存在。
            死亡:     核心容器销毁,对象销毁
        总结:容器在,对象在。 容器亡,对象亡。
        多例对象:prototype,每次从核心容器获取对象都是不一样的对象。     采用延迟加载。
            出生:     从核心容器获取对象时创建。
            活着:     只要是在使用过程中都活着。
            死亡:java垃圾回收机制。 当对象长时间没有使用,会被Java垃圾处理器回收。因为Spring不知到什么时候销毁对象, 所以不销毁多例对象。



        -->
<!--spring 的依赖注入
        依赖注入:       Dependency Injection
        IOC(控制反转)的作用:   降低程序之间、类之间的依赖
        依赖关系的管理:        交由Spring框架来维护。 当我们需要对象时由Spring框架为我们
    提供。     而我们要做的就是 在配置文件中声明bean即可。
        依赖关系的维护(依赖关系的注入):
            能注入的数据,三类:
                经常变化的数据,并不适用注入的方式。
                经常变化的数据,并不适用注入的方式。
                经常变化的数据,并不适用注入的方式。
                基本数据类型,String类型。        为了对象的初始化????
                bean类型(在配置文件中或者注解配置过的bean)
                复杂类型/集合类型
            注入的方式,三种:
                使用构造函数提供,涉及 <constructor-arg name="name" value="名称"></constructor-arg>标签。
                    标签出现位置:bean标签的内部。
                    标签属性:
                        name:       用于指定参数(名称匹配)
                        value:      给基本数据类型和String类型赋值
                        ref:        用于指定其他的bean数据类型。也就是拿在配置文件中的bean 类为参数赋值。
                    弊端: 由于实际开发中业务复杂,我们无法确定需要传入多少个参数。但是如果没
                        有创造对应的构造函数又没法使用Spring来为我们创建对象。 所以这种注入方
                        式  一般是在 没有选择余地的时候使用。

                使用实体类的set方法提供, 涉及标签<constructor-arg name="name" value="名称"></constructor-arg>
                    标签出现的位置:bean标签内部
                    标签属性:
                        name:       用于指定实体类的set方法名称(除去set)
                        value:      同上。
                        ref:        同上。
                    优势:     解决了用构造函数注入数据的弊端。
                使用注解提供

        -->




    代码展示 如下:

<!--使用默认构造函数提供、指定参数类型提供。
            注意:但是单例对象 同一实体类会被创建多个对象-->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>

    <!--配置一个日期对象-->
    <bean id="now" class="java.util.Date"></bean>
    <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="名称"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>

    <!--类属性的set方法 注入-->
    <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl2">
        <property name="userName" value="name的参数值"></property>
        <property name="age" value="22"></property>
        <property name="birthday" ref="now"></property>
    </bean>

    <!--复杂类型和集合类型的数据注入。         注入方式:  实体类的set方法注入数据、通过构造方法注入。 推荐使用set方式注入
            <property></property>内部嵌入 <value></value>标签 赋值。具体请百度。
            用于给list结构标签注入数据的标签有
                list、set、array
            用于给Map结构标签注入数据的标签有
                map、properties
            总结:结构相同, 注入数据的标签可以互换。

    -->

    <bean id="accountService4" class="com.itheima.service.impl.AccountServiceImpl3">
        <property name="mystrs">
            <array>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </array>
        </property>

        <property name="myList">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
                <value>list4</value>
            </list>
        </property>

        <property name="mySet">
            <array>
                <value>set2222</value>
                <value>set3333</value>
                <value>set5555</value>
            </array>
        </property>

        <property name="myMap">
            <props>
                <prop key="AAA">aaa</prop>
                <prop key="BBB">bbb</prop>
                <prop key="CCC">ccc</prop>
            </props>

        </property>

        <property name="myProps">
            <map>
                <entry key="test1">
                    <value>1111</value>
                </entry>

                <entry key="test2" value="22222"></entry>
            </map>
        </property>
    </bean>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值