zoukankan      html  css  js  c++  java
  • spring框架的概述以及spring中基于XML的IOC配置(1)

    spring共四天
    第一天:spring框架的概述以及spring中基于XML的IOC配置
    第二天:spring中基于注解的IOC和ioc的案例
    第三天:spring中的aop和基于XML以及注解的AOP配置
    第四天:spring中的JdbcTemlate以及Spring事务控制
    -----------------------------------------------------

    一、内容大纲
    1、spring的概述
     spring是什么
     spring的两大核心
     spring的发展历程和优势
     spring体系结构
    2、程序的耦合及解耦
     曾经案例中问题
     工厂模式解耦
    3、IOC概念和spring中的IOC
     spring中基于XML的IOC环境搭建
    4、依赖注入(Dependency Injection)


    二、spring概述

    1.jdbc小案例

    package com.iteima.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    /**
     * 程序的耦合
     *      耦合:程序间的依赖关系
     *          包括:
     *              类之间的依赖
     *              方法间的依赖
     *      解耦:
     *          降低程序间的依赖关系
     *      实际开发中:
     *          应该做到:编译期不依赖,运行时才依赖。
     *      解耦的思路:
     *          第一步:使用反射来创建对象,而避免使用new关键字。
     *          第二步:通过读取配置文件来获取要创建的对象全限定类名
     *
     */
    public class JdbcDemo1 {
        public static void main(String[] args) throws  Exception{
            //1.注册驱动
    //        DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            Class.forName("com.mysql.jdbc.Driver");
    
            //2.获取连接
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eesy","root","1234");
            //3.获取操作数据库的预处理对象
            PreparedStatement pstm = conn.prepareStatement("select * from account");
            //4.执行SQL,得到结果集
            ResultSet rs = pstm.executeQuery();
            //5.遍历结果集
            while(rs.next()){
                System.out.println(rs.getString("name"));
            }
            //6.释放资源
            rs.close();
            pstm.close();
            conn.close();
        }
    }

    通过此案例,可以得出我们以前写的程序独立性很差,以及解决耦合性过高的思路

    2.工厂模式解耦

    bean.properties

    accountService=com.itheima.service.impl.AccountServiceImpl
    accountDao=com.itheima.dao.impl.AccountDaoImpl

    beanFactory

    package com.itheima.factory;
    
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * 一个创建Bean对象的工厂
     *
     * Bean:在计算机英语中,有可重用组件的含义。
     * JavaBean:用java语言编写的可重用组件。
     *      javabean >  实体类
     *
     *   它就是创建我们的service和dao对象的。
     *
     *   第一个:需要一个配置文件来配置我们的service和dao
     *           配置的内容:唯一标识=全限定类名(key=value)
     *   第二个:通过读取配置文件中配置的内容,反射创建对象
     *
     *   我的配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
        //定义一个Properties对象
        private static Properties props;
    
        //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器
        private static Map<String,Object> beans;
    
        //使用静态代码块为Properties对象赋值
        static {
            try {
                //实例化对象
                props = new Properties();
                //获取properties文件的流对象
                InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
                props.load(in);
                //实例化容器
                beans = new HashMap<String,Object>();
                //取出配置文件中所有的Key
                Enumeration keys = props.keys();
                //遍历枚举
                while (keys.hasMoreElements()){
                    //取出每个Key
                    String key = keys.nextElement().toString();
                    //根据key获取value
                    String beanPath = props.getProperty(key);
                    //反射创建对象
                    Object value = Class.forName(beanPath).newInstance();
                    //把key和value存入容器中
                    beans.put(key,value);
                }
            }catch(Exception e){
                throw new ExceptionInInitializerError("初始化properties失败!");
            }
        }
    
        /**
         * 根据bean的名称获取对象(获取的是单例的对象)
        单例对象对于本例更加适合,执行效率更高
    *
    @param beanName * @return */ public static Object getBean(String beanName){ return beans.get(beanName); } /** * 根据Bean的名称获取bean对象 * @param beanName * @return public static Object getBean(String beanName){ Object bean = null; try { String beanPath = props.getProperty(beanName); // System.out.println(beanPath); bean = Class.forName(beanPath).newInstance();//每次都会调用默认构造函数创建对象,获取的是多例的对象 }catch (Exception e){ e.printStackTrace(); } return bean; }*/ }
    package com.itheima.ui;
    
    import com.itheima.factory.BeanFactory;
    import com.itheima.service.IAccountService;
    
    /**
     * 模拟一个表现层,用于调用业务层
     */
    public class Client {
    
        public static void main(String[] args) {
            //IAccountService as = new AccountServiceImpl();
            for(int i=0;i<5;i++) {
                IAccountService as = (IAccountService) BeanFactory.getBean("accountService");
                System.out.println(as);
                as.saveAccount();
            }
    
        }
    }
    /**
     * 账户的业务层实现类
     */
    public class AccountServiceImpl implements IAccountService {
    
    //    private IAccountDao accountDao = new AccountDaoImpl();
    
        private IAccountDao accountDao = (IAccountDao)BeanFactory.getBean("accountDao");
        /**
         * 获取spring的Ioc核心容器,并根据id获取对象
         *
         * ApplicationContext的三个常用实现类:
         *      ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用)
         *      FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
         *
         *      AnnotationConfigApplicationContext:它是用于读取注解创建容器的,是明天的内容。
         *
         * 核心容器的两个接口引发出的问题:
         *  ApplicationContext:     单例对象适用              采用此接口
         *      它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
         *
         *  BeanFactory:            多例对象使用
         *      它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
         * @param args
         */

    一.入门案例

    1.引入坐标位置、导入配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.itheima</groupId>
        <artifactId>day01_eesy_03spring</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
        </dependencies>
    </project>

    2.导入约束

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

    3.把对象的创建交给spring来管理

    <?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来管理-->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
    
        <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
    </beans>

    4.创建对象

        public static void main(String[] args) {
            //1.获取核心容器对象
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    //        ApplicationContext ac = new FileSystemXmlApplicationContext("C:\Users\zhy\Desktop\bean.xml");
            //2.根据id获取Bean对象
            IAccountService as  = (IAccountService)ac.getBean("accountService");
            IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
    
            System.out.println(as);
            System.out.println(adao);
            as.saveAccount();

    解析配置文件、创建对象、存入Map都让spring做了


    二、spring对bean的管理细节

    1.创建bean的三种方式
      <!--创建Bean的三种方式 -->
        <!-- 第一种方式:使用默认构造函数创建。
                在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
                采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
    
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
        -->
    
        <!-- 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
        <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
        <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
        -->
    
        <!-- 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
        <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>
        -->
        2.bean对象的作用范围
     bean的作用范围调整
            bean标签的scope属性:
                作用:用于指定bean的作用范围
                取值: 常用的就是单例的和多例的
                    singleton:单例的(默认值)
                    prototype:多例的
                    request:作用于web应用的请求范围
                    session:作用于web应用的会话范围
                    global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
    
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="prototype"></bean>
    
    



    3.bean对象的生命周期
        <!-- bean对象的生命周期
                单例对象
                    出生:当容器创建时对象出生
                    活着:只要容器还在,对象一直活着
                    死亡:容器销毁,对象消亡
                    总结:单例对象的生命周期和容器相同
                多例对象
                    出生:当我们使用对象时spring框架为我们创建
                    活着:对象只要是在使用过程中就一直活着。
                    死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
         -->
        <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
              scope="prototype" init-method="init" destroy-method="destroy"></bean>
    
    

      三、spring的依赖注入

    依赖注入:
    Dependency Injection
    IOC的作用:
    降低程序间的耦合(依赖关系)
    依赖关系的管理:
    以后都交给spring来维护
    在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
    依赖关系的维护:
    就称之为依赖注入。
    依赖注入:
    能注入的数据:有三类
    基本类型和String
    其他bean类型(在配置文件中或者注解配置过的bean)
    复杂类型/集合类型
    注入的方式:有三种
    第一种:使用构造函数提供
    第二种:使用set方法提供
    第三种:使用注解提供(明天的内容)

    1.构造函数注入

    使用的标签:constructor-arg
    标签出现的位置:bean标签的内部
    标签中的属性
    type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
    index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
    name:用于指定给构造函数中指定名称的参数赋值
    ===以上三个(name常用)用于指定给构造函数中哪个参数赋值===
    value:用于提供基本类型和String类型的数据
    ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

    优势:
    在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    弊端:
    改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
    bean.xml
    <bean id="accountService" 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>

    <!-- 配置一个日期对象 -->
    <bean id="now" class="java.util.Date"></bean>
    accountServiceImpl
    package com.itheima.service.impl;
    
    import com.itheima.service.IAccountService;
    
    import java.util.Date;
    
    /**
     * 账户的业务层实现类
     */
    public class AccountServiceImpl implements IAccountService {
    
        //如果是经常变化的数据,并不适用于注入的方式
        private String name;
        private Integer age;
        private Date birthday;
    
        public AccountServiceImpl(String name,Integer age,Date birthday){
            this.name = name;
            this.age = age;
            this.birthday = birthday;
        }
    
        public void  saveAccount(){
            System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
        }
    
    
    }
    2.Set方法注入
    涉及的标签:property
    出现的位置:bean标签的内部
    标签的属性
    name:用于指定注入时所调用的set方法名称
    value:用于提供基本类型和String类型的数据
    ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    优势:
    创建对象时没有明确的限制,可以直接使用默认构造函数
    弊端:
    如果有某个成员必须有值,则获取对象是有可能set方法没有执行。

    bean.xml
        <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
            <property name="name" value="TEST" ></property>
            <property name="age" value="21"></property>
            <property name="birthday" ref="now"></property>
        </bean>

    accountServiceImpl2

    package com.itheima.service.impl;
    
    import com.itheima.service.IAccountService;
    
    import java.util.Date;
    
    /**
     * 账户的业务层实现类
     */
    public class AccountServiceImpl2 implements IAccountService {
    
        //如果是经常变化的数据,并不适用于注入的方式
        private String name;
        private Integer age;
        private Date birthday;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public void  saveAccount(){
            System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
        }
    
    
    }

    3.复杂类型注入

    package com.itheima.service.impl;
    
    import com.itheima.service.IAccountService;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Properties;
    import java.util.Set;
    import java.util.Map;
    
    /**
     * 账户的业务层实现类
     */
    public class AccountServiceImpl3 implements IAccountService {
    
        private String[] myStrs;
        private List<String> myList;
        private Set<String> mySet;
        private Map<String,String> myMap;
        private Properties myProps;
    
        public void setMyStrs(String[] myStrs) {
            this.myStrs = myStrs;
        }
    
        public void setMyList(List<String> myList) {
            this.myList = myList;
        }
    
        public void setMySet(Set<String> mySet) {
            this.mySet = mySet;
        }
    
        public void setMyMap(Map<String, String> myMap) {
            this.myMap = myMap;
        }
    
        public void setMyProps(Properties myProps) {
            this.myProps = myProps;
        }
    
        public void  saveAccount(){
            System.out.println(Arrays.toString(myStrs));
            System.out.println(myList);
            System.out.println(mySet);
            System.out.println(myMap);
            System.out.println(myProps);
        }
    
    
    }
    <?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">
    
        <!-- 复杂类型的注入/集合类型的注入
            用于给List结构集合注入的标签:
                list array set
            用于个Map结构集合注入的标签:
                map  props
            结构相同,标签可以互换
        -->
        <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3">
            <property name="myStrs">
                <set>
                    <value>AAA</value>
                    <value>BBB</value>
                    <value>CCC</value>
                </set>
            </property>
    
            <property name="myList">
                <array>
                    <value>AAA</value>
                    <value>BBB</value>
                    <value>CCC</value>
                </array>
            </property>
    
            <property name="mySet">
                <list>
                    <value>AAA</value>
                    <value>BBB</value>
                    <value>CCC</value>
                </list>
            </property>
    
            <property name="myMap">
                <props>
                    <prop key="testC">ccc</prop>
                    <prop key="testD">ddd</prop>
                </props>
            </property>
    
            <property name="myProps">
                <map>
                    <entry key="testA" value="aaa"></entry>
                    <entry key="testB">
                        <value>BBB</value>
                    </entry>
                </map>
            </property>
        </bean>
    
    </beans>
    
    
    
  • 相关阅读:
    使用Spring AOP实现MySQL数据库读写分离案例分析
    mysql的备份(文档的内容小编都已经验证过了)
    【信息化】MySQL数据库简介
    基于MySQL的分布式数据库TDSQL十年锻造经验分享
    MySQL数据库丢失数据场景分析
    微博的MySQL数据库优化实践经验
    数据库MySQL调优实战经验总结
    让数据库跑的更快的7个MySQL优化建议
    一文看懂 MySQL 分区和分表,提高表增删改查效率
    三分钟掌握SQL Server迁移Mongodb
  • 原文地址:https://www.cnblogs.com/lsk-130602/p/12207319.html
Copyright © 2011-2022 走看看