JavaWeb笔记(24)-spring框架基础

  1. spring框架
1. Spring是分层的Java SE/EE应用 full-stack轻量级开源框架
    以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核
    提供了展现层Spring MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术
    还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架
2. Spring优势:
    a. 方便解耦,简化开发:
        降低程序之间的依赖
        应该做到编译期不依赖,运行期才依赖
        例如:
            //此方式注册驱动如果没有mysql-jar包,编译期报错
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            //使用Class注册驱动如果没有mysql-jar包,运行期抛出异常
            Class.forName("com.mysql.jdbc.Driver");
    b. AOP编程的支持
    c. 声明式事务的支持
    d. 方便程序测试
    e. 方便集成各种框架
    f. 降低JavaEE API使用难度
    g. Java源码是经典的学习范例
3. 程序的耦合:
    a. 程序间的依赖关系:程序的编译依赖于其他的程序
        1. 类之间的依赖
        2. 方法之间的依赖
    b. 解耦思想:
        1. 使用反射来创建对象,而避免使用new关键字
        2. 通过读取配置文件来获取要创建的对象的全限定类名
    c. 开发中应用:
        1. 创建工厂类来生产Bean对象:
            Bean在计算机英语中表示可重用组件
        2. JavaBean:
            JavaBean指用Java语言编写的可重用组件
            JavaBean范围远大于实体类
        3. 需要一个配置文件来配置需要生产的Bean对象
            配置内容:唯一标识=全限定类名(key=value)
        4. 通过读取配置文件配置的内容,反射创建对象
            配置文件可以使用xml或properties文件
            Object obj = Class.forName(beanPath).newInstance();
                * 每次调用newInstance方法都会调用一次默认构造函数
                * 此时创建的对象形式为多例的
        5. 工厂类的构建:
            * 创建一个静态私有的Properties对象用于加载配置文件
            * 创建一个静态容器Map对象用于保存配置文件中要求的对象
            *static静态代码块中读取配置文件,利用反射创建对象,将配置文件中的key和新创建的对象存储Map容器
            * 在静态方法中返回Map容器中早已创建好的对象
            * 由于静态代码块仅在类加载时执行一次,因此该工厂调用成员方法创建的对象都是同一个,对象为单例形式
        6. 使用工厂生产Bean对象先决条件:
            业务层和持久层中几乎可以改变的成员变量
  1. IoC控制:Inverse Of Control 反转控制
1. 原始创建对象形式:
    由app寻找资源,然后创建对象(new形式)
2. 控制反转创建形式:
    由app向工厂索要对象,工厂控制资源(工厂类形式)
    将原本自主创建对象的权力交予工厂,即控制反转。包括依赖注入和依赖查找
  1. 使用spring的IOC解决程序耦合
1. 下载解压spring framework:
    spring-framework-5.0.2.RELEASE-dist
2. 导入相关spring相关jar包:
    spring-aop-5.0.2.RELEASE.jar        --      基于注解开发的必备jar包
    spring-beans-5.0.2.RELEASE.jar      --      中间4个为核心容器的jar包
    spring-context-5.0.2.RELEASE.jar
    spring-core-5.0.2.RELEASE.jar
    spring-expressoin-5.0.2.RELEASE.jar
    spring-jcl-5.0.2.RELEASE.jar        --      集成了apache的日志组件做成了自己的jar包
    使用坐标定位时仅需要定位spring-context即可:
        * 当前工程依赖于spring-context
        * spring-context依赖于spring-beans,spring-aop,spring-expression,spring-core
        * spring-aop依赖于spring-beans,spring-core
        * spring-beans依赖于spring-core
        * spring-expression依赖于spring-core
        * spring-core依赖于spring-jcl
3. 创建xml配置文件,并导入约束:
    /resource/bean.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">
        <!--配置相关信息-->
    </beans>
4. 使用bean标签将对象的创建交给框架:
    <bean id="唯一标识key" class="需要创建的对象的全限定类名"></bean>
5. 获取spring核心容器,并根据id获取创建的对象:
    //获取核心容器对象
    ApplicationContext coreObj = new ClassPathXmlApplicationContext("配置文件名(bean.xml)")
    //依据id获取Bean对象
    E element = (E) coreObj.getBean("唯一标识id");
    //E element = (E) coreObj.getBean("唯一标识id", E.class);
    * 获取核心容器的三种形式:
        1. ClassPathXmlApplicationContext:仅能加载类路径下的配置文件
        2. FileSystemXmlApplicationContext:可以加载任意磁盘路径下的配置文件(需要有访问权限)
        3. AnnotationConfigApplicationContext:用于读取注解创建容器
    * 核心容器的两个接口:
        1. ApplicationContext:单例对象适用,但是可以根据配置设置立即或延迟,因此开发更为常用
            在构建核心容器时,创建对象为立即加载方式。即,读取完配置文件后,立即创建所有配置中的对象
        2. BeanFactory:多例对象适用
            在构建核心容器时,创建对象为延迟加载方式。即,仅由id获取对象时创建该对象
6. spring对Bean的管理细节:
    a. 创建bean的三种方式:
        1. 使用默认构造函数创建对象:
            在spring的配置文件中使用bean标签,配置id和class属性,且没有其他属性和标签,调用默认构造函数创建
                <bean id="唯一标识key" class="需要创建的对象的全限定类名"></bean>
            如果此时类中没有默认构造函数(重写了带参构造函数但是没有重写默认构造函数),则不能创建bean对象
        2. 使用其他类中的方法创建对象:
            在spring的配置文件中使用bean标签,配置id,factory-bean,factory-method属性,调用工厂类中方法创建
                <bean id="唯一标识key" class="创建对象的工厂的全限定类名"></bean>
                <bean id="唯一标识key" factory-bean="工厂唯一标识id" factor-method="创建对象的方法"></bean>
        3. 使用其他类中的静态方法创建对象:
            在spring的配置文件中使用bean标签,配置id,class,factory-method属性,调用工厂类中静态方法创建
                <bean id="唯一标识key" class="工厂全限定类名" factor-method="创建对象的静态方法"></bean>
    b. bean对象的作用范围:
        1. 默认情况下,bean标签创建对象的形式是单例的
        2. 通过bean标签的scope属性来指定bean的作用范围:
            * singleton:单例的(默认值)
            * prototype:多例的
            * request:作用于web应用的请求范围
            * session:作用于web应用的会话范围
            * global-session:作用于集群环境的会话范围(全局会话范围),当不是集群范围时,等同于session范围
    c. bean对象的生命周期:
        1. 单例对象:
            生命周期与容器相同:容器创建时创建,容器销毁时销毁
            调用ClassPathXmlApplicationContext的close方法销毁容器
        2. 多例对象:
            生命周期:使用对象时spring框架创建,当对象长时间没有使用且无其他对象引用时有java垃圾回收机制回收
7. spring中的依赖注入:
    a. 依赖关系管理:
        表示层调用业务层,业务层调用持久层这是必然会出现的
        于是将调用间的对象创建交由spring,这种依赖关系有spring管理
        我们只需要在配置文件中说明,在当前类中需要使用其他类的对象,其他类的对象有spring提供
        依赖关系的维护称为:依赖注入
    b. 能够注入的数据:
        1. 基本类型和String
        2. 其他bean类型(在配置文件中或者注解配置过的bean)
        3. 复杂类型/集合类型
    c. 注入方式:
        1. 使用构造函数
            被注入的类中重写了带参构造函数时,在bean标签的配置内部加入constructor-arg标签
            <bean id="唯一标识key" class="需要创建的对象的全限定类名">
                <constructor-arg></constructor-arg>
                <!--
                    constructor-arg标签中的属性:
                    * type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
                    * index:用于指定注入数据在构造函数中参数的索引,从0开始
                    * name:用于指定注入数据在构造函数中的名称                              (常用形式)
                    =======================以上3个属性用于确定给构造函数中哪个参数赋值==================
                    * value:指定参数注入的值,仅限基本类型和String类型
                    * ref:用于引用关联的bean对象,仅限IOC容器中配置过的对象
                -->
            </bean>
            例如:
                当需要注入的参数为Date类型数据时,并不能直接使用value赋值一个字符串
                而需要另外定义一个bean对象,反射创建一个Date对象,用constructor-arg的ref属性引用创建的Date对象
                <bean id="now" class="java.util.Date"></bean>
                <bean id="xxx" class="xxx.xxx.xxx">
                    <constructor-arg name="birthday" ref="now"></constructor-arg>
                </bean>
            优势:
                由于没有默认构造函数,所以创建对象时,配置注入参数的操作是必须的,否则无法创建对象
            劣势:
                改变了bean对象的实例化方式,如果不使用该bean对象也同样需要配置参数注入
        2. 使用set方法
            被注入的类中必须含有参数的set方法,可以不写get方法。在bean标签内部使用property标签
            <bean id="唯一标识key" class="需要创建的对象的全限定类名">
                <property></property>
                <!--
                    property标签中的属性:
                    * name:用于指定注入数据在set方法中的属性名称
                    * value:指定参数注入的值,仅限基本类型和String类型
                    * ref:用于引用关联的bean对象,仅限IOC容器中配置过的对象
                -->
            </bean>
            优劣与构造方法创建相反
            复杂数据类型注入:
                * 给List结构的参数注入:
                    在property内部有子标签list,set,array,在通过子标签的子标签<value></value>进行元素赋值
                    <property name="myList">
                        <list>
                            <value>索引为0的值</value>
                            <value>索引为1的值</value>
                            ...
                        </list>
                    </property>
                * 用于给map结构的参数注入:
                    在property内部有子标签map,propos,在通过子标签的key和value为元素赋键值
                    <property name="myMap">
                        <map key="键" value="值"></map>
                    </property>
                * 相同结构的注入操作标签可以互换,即List可以使用set/list/array标签都行
        3. 使用注解
  1. 举例:使用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">
    <!-- 配置Service -->
    <bean id="accountService" class="cn.mysilent.service.impl.AccountServiceImpl">
        <!-- 注入dao -->
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--配置Dao对象-->
    <bean id="accountDao" class="cn.mysilent.dao.impl.AccountDaoImpl">
        <!-- 注入QueryRunner -->
        <property name="runner" ref="runner"></property>
    </bean>

    <!--配置QueryRunner,为了使每个查询不相互干扰,配置该对象的创建为多例prototype-->
    <!--如果QueryRunner是单例对象,则面临多个dao使用时,可能引发线程安全问题-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--注入数据源-->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--连接数据库的必备信息-->
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="用户名"></property>
        <property name="password" value="密码"></property>
    </bean>
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值