Spring学习【1】

1. Spring体系结构:

2. 耦合:

①:含义:对象间的依赖关系。

②:耦合的说明:

这里再提一下内聚,假设我们住在一个别墅里,别墅里有很多卧室,我住在其中的一个卧室,姐姐住在另一个卧室,我的卧室里有我的东西,姐姐卧室有她的东西,我们除了吃饭聊天彼此互不干扰,达到了【高内聚】。有一天,我的房间里面窗户坏了,于是第二天我叫来修理公司的人向他们说明了情况,人家一看,说道:“你这窗户焊死了!根本没法修,只能破坏掉重新装一个可拆卸的。”我无奈道:“那您看着弄吧。”修理完后,费用比原先只换一个玻璃高了不少。 ——窗户和我的房间之间具有依赖关系,这其实就是耦合度,窗户焊死,耦合度自然高,修改的代价也高。

③:解耦:降低耦合度。

(1):解耦的方式:

——第一步:使用反射来创建对象,而避免使用new关键字;
——第二步:通过读取配置文件来获取要创建的对象全限定类名。

(2):简单例子说明解耦:

——注册Mysql驱动的解耦:

        //1.注册驱动
        
        /**
         * 如果你没有mysql的驱动包,那么此种方式程序在编译期就会报错,不管有没有执行它
         */
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        /**
         * 此种方式程序在运行期才会报错,如果没有执行它就不会报错
         */
        Class.forName("com.mysql.jdbc.Driver");

其实这样的方式就是给注册驱动这一过程包装了一下而已,它里面实际上就执行了registerDriver的代码,它被包含在静态代码块中,也就是说创建了这个类的对象就要执行这段代码,所以可以用Class.forName()代替。

package com.mysql.cj.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

——简单工厂解耦:

创建一个工厂类,这个工厂类根据你提供的字符串来创建不同的你所需要的对象,而这个字符串可以通过配置文件的形式给出,这样一来程序不会出现编译期的错误,而知道错误后不用修改程序中的字符串,仅通过配置文件修改也方便了许多。

简单工厂模式:讲解链接

3. ioc控制反转:

①:含义:控制创建对象的权利转移给框架。

②:目的:降低耦合度。

③: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="accountDao" class="cn.xupt.dao.impl.AccountDao"></bean>

    <bean id="accountService" class="cn.xupt.service.AccountService"></bean>
</beans>

④:如何使用:

(1):使用核心容器的接口ApplicationContext来创建对象:

        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        IAccountDao accountDao = (AccountDao) ac.getBean("accountDao");
        AccountService accountService = ac.getBean("accountService", AccountService.class);

        accountDao.saveAccount();
        accountService.saveAccount();

——注意:只要一读取配置文件,配置文件内配置的对象都会被创建;

——适用:单例对象。

(2):使用核心容器接口BeanFactory创建对象:

        Resource resource = new ClassPathResource("bean.xml");
        BeanFactory factory = new XmlBeanFactory(resource);
        IAccountDao accountDao = (IAccountDao) factory.getBean("accountDao");
        accountDao.saveAccount();

——注意:什么时候根据id获取对象,什么时候创建;

——适用:多例对象。

⑤:bean对象的三种创建方式:

    <!--spring bean的默认配置方式,创建对象时使用默认的构造函数创建,如果没有默认构造函数会报错-->
    <bean id="accountService" class="cn.xupt.service.AccountService"></bean>

    <!--spring bean被工厂(某个类)中的方法创建并存入spring容器-->
    <bean id="instanceFactory" class="cn.xupt.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

    <!--spring bean被工厂(某个类)中的静态方法创建并存入spring容器-->
    <bean id="accountService" class="cn.xupt.factory.StaticFactory" factory-method="getAccountService"></bean>

说明:

——第一种方式:通常自己创建的类,可以改变的类可以选择使用此种配置方式;

——第二和第三种方式:一般我们导入jar包后不能轻易改变jar包中某个类的源码,这时我们可以选择这两种方式来创建这个类中某个方法返回值类型的对象

⑥:bean对象的作用域:

(1):说明:

作用域指的是这个bean对象可以在什么范围内使用。

(2):调整:

——配置scope属性来改变bean对象的作用域:

    <bean id="accountService" class="cn.xupt.service.AccountService" scope="prototype"></bean>

——scope属性的取值有:

singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session

——global-session的说明:多台主机之间共享的域。

⑦:bean对象的生命周期:

(1):说明:

对象的“一生“

(2):配置:

    <bean id="accountService" class="cn.xupt.service.AccountService" 
          scope="singleton" init-method="init" destroy-method="destroy"></bean>

——小贴士:init和dertroy方法是accountService类中有的。

(3):单例和多例对象生命周期的差异

——单例对象:

————创建:spring容器创建,对象创建(立即加载);

————存在:容器存在,对象就存在;

————销毁:容器销毁,对象就销毁;

————总结:单例对象的生命周期和容器的生命周期相同。

——多例对象:

————创建:使用对象时对象创建(延迟加载);

————存在:只要对象在被使用,它就存在;

————销毁:对象长时间不用,由Java的垃圾回收器回收。

——小知识:Java使用多态时,创建的接口对象不能使用其子类独有的方法:

    IUserDao userdao = new UserDao();

————例如:userdao不能使用UserDao中特有的方法(也就是IUserDao中没有的方法)

4. DI依赖注入:

①:含义:有依赖关系的类放到容器中,解析出这些类的实例,就是依赖注入。

②:目的:解耦。

③:可以注入的三种类型:

(1):基本类型和String类型;

(2):bean对象;

(3):复杂类型/集合类型。

④:三种注入方式:

(1):构造函数注入:

    <!--构造函数注入-->
    <bean id="accountService" class="cn.xupt.service.AccountService">
        <constructor-arg name="name" value="嘤嘤嘤"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="birthday" ref="date"></constructor-arg>
    </bean>

    <!-- 配置一个日期对象 -->
    <bean id="date" class="java.util.Date"></bean>

——优点:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。

——缺点:改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

(2):set方法注入:

    <!--set方法注入-->
    <bean id="accountService2" class="cn.xupt.service.AccountService">
        <property name="name" value="set方法注入"></property>
        <property name="age" value="20"></property>
        <property name="birthday" ref="date"></property>
    </bean>

    <!-- 配置一个日期对象 -->
    <bean id="date" class="java.util.Date"></bean>

——优点:创建对象时没有明确的限制,可以直接使用默认构造函数。

——缺点:如果有某个成员必须有值,则获取对象是有可能set方法没有执行。

⑤:复杂类型/集合类型的set方法注入:

    <!--复杂类型的set方法注入-->
    <bean id="accountService3" class="cn.xupt.service.AccountService3">
        <property name="myStrings">
            <array>
                <value>AAA</value>
                <value>BBB</value>
            </array>
        </property>
        <property name="myLists">
            <array>
                <value>AAA</value>
                <value>BBB</value>
            </array>
        </property>
        <property name="mySets">
            <array>
                <value>AAA</value>
                <value>BBB</value>
            </array>
        </property>
        <property name="myMaps">
            <map>
                <entry key="aaa" value="aaa"></entry>
                <entry key="bbb" value="bbb"></entry>
            </map>
        </property>
        <property name="myProps">
            <map>
                <entry key="aaa" value="aaa"></entry>
                <entry key="bbb" value="bbb"></entry>
            </map>
        </property>
    </bean>

注意:

集合、数组的标签可以一样;

map和properties的标签可以一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值