zoukankan      html  css  js  c++  java
  • Spring框架学习01

    写在前面

    这学期给自己定的目标有两个,一个是安卓开发一个是SSM。正好近期APP的十天冲刺告一段落,系主任让我们好好放假玩。五一这几天正好适合拿来学习SSM框架。今天先开了个头,学了下Spring框架的基础知识,为什么使用Spring框架等等。

    为什么要使用Spring框架?

    在我们学习代码的路上,老是听到这样一句话:我们写程序讲究的是一个高内聚低耦合。可这句话是什么意思呢?又有什么用呢?为什么这么做呢?首先,高内聚低耦合的意思就是说,我们要降低程序与程序之间的联系,不会牵一发而动所有。试想,在开发里我改了一个模块,所有的系统都要改,这还了得?所以这种开发规范可以很好的降低我们开发的难度,使得开发更加简单,更加容易分工。那么我们在程序中什么情况下会遇到呢?先看一段经典的java web的JDBC代码:

    public class AccountServiceImpl implements IAccountService {
         private IAccountDao accountDao = new AccountDaoImpl();
        @Override
        public void saveAccount() {
            accountDao.saveAccount();
        }
    

    这是一段经典的java web代码,我们在service层实现service接口,且new了一个dao接口来实现方法。很明显地我们可以看到,这里的程序耦合度十分的高。要是我们的dao接口出了什么问题,service就会崩掉,无法使用。我们肯定要避免这种结果的。那怎么搞呢?我们可以将他new的权限剥夺,让他变成被动,让别人给他。这样他与dao接口的耦合就会很明显的降低了。这其实就是Spring框架的核心思想:IOC(控制反转)。

    Spring框架的IOC原理和使用

    原理

    我们来看一张图,这是典型的结构:

    那么我们使用了spring框架后呢?

    可以明显地看到耦合度降低了。但有人可能要说了,这不还是有耦合度嘛。需要注意的是我们不可能完全避免耦合,只能做到低耦合。这种方式的耦合度要比new对象的耦合度低的多。

    使用

    主程序代码:

        /**
         * 获取spring的Ioc核心容器,并根据id获取对象
         *
         * ApplicationContext的三个常用实现类
         *  ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下.(更常用,指1和2)
         *  FileSystemApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
         *  AnnotationConfigApplicationContext:它是用于读取注解创建容器的.
         *  核心容器的两个接口引发出的问题:
         *  ApplicationContext(单例对象适用,多用此接口):它在构建核心容器时创建对象采取的策略是采用立即加载的方式,只要一读取完配置文件马上就创建配置文件中配置的对象.
         *  BeanFactory(多例对象适用):它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式,也就是说什么时候根据id获取对象,什么时候才创建对象.
         * @param args
         */
        public static void main(String[] args) {
            //1.获取核心容器对象
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            ApplicationContext ac = new FileSystemXmlApplicationContext("C:\Users\10985\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();
            //-----------BeanFactory-------
            Resource resource = new ClassPathResource("bean.xml");
            BeanFactory factory = new XmlBeanFactory(resource);
            IAccountService as = (IAccountService) factory.getBean("accountService");
            System.out.println(as);
        }
    

    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">
        <!-- 把对象的创建交给spring来管理-->
        <bean id="accountService" class="com.liuge.service.impl.AccountServiceImpl"></bean>
        <bean id="accountDao" class="com.liuge.dao.impl.AccountDaoImpl"></bean>
    </beans>
    

    可以看到,使用spring的方式很简单,只需要正确配置好文件即可.

    spring中的依赖注入

    依赖注入有三种方式,这里我们学习了前两种:使用构造函数提供,使用set方法提供(更常用)
    可注入的对象类型有三种:基本数据类型和String,其他bean类型(在配置文件中或者注解配置过的bean), 复杂类型(集合类),详见bean.xml代码
    先定义三个类。

    public class AccountServiceImpl1 implements IAccountService {
        /**
         * 如果是经常变化的方式,并不适合用注入的方式
         */
        private String name;
        private Integer age;
        private Date birthday;
        public AccountServiceImpl1(String name, Integer age, Date birthday){
            this.name = name;
            this.age = age;
            this.birthday = birthday;
        }
        @Override
        public void saveAccount() {
            System.out.println("service中的saveAccount方法执行了..."+name+","+age+","+birthday);
        }
    }
    
    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;
        }
    
        @Override
        public void saveAccount() {
            System.out.println("service中的saveAccount方法执行了..."+name+","+age+","+birthday);
        }
    }
    

    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;
    }
    
    @Override
    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);
    }
    

    }

    
    bean.xml:
    


    <!-- 构造函数注入:
        使用的标签:constructor-arg
        标签出现的配置:bean标签内部
        标签中的属性:
            type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
            index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值.索引的位置从0开始.
            name:用于指定给构造函数中指定名称的参数赋值(常用)
            ============以上三个用于指定给构造函数中哪个参数赋值==========
            value:用于提供基本类型和string类型的数据
            ref:用于指定其他的bean类型.指在spring的Ioc核心容器中出现过的bean对象
         优势:
            在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功.
         弊端:
            改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须使用.
    -->
    <bean id="accountService" class="com.liuge.service.impl.AccountServiceImpl1">
        <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>
    <!-- set方法注入  (更常用)
        涉及的标签:property标签
        出现的位置:bean标签的内部
        标签的属性:
            name:用于指定注入时所调用的set方法名称
            value:用于提供基本类型和string类型的数据
            ref:用于指定其他的bean类型.指在spring的Ioc核心容器中出现过的bean对象
         优势:
            创建对象时没有明确的限制,可以直接使用默认构造函数
         弊端:
            如果有某个成员必须有值,则获取对象时有可能set方法没有执行.
    -->
    <bean id="accountService2" class="com.liuge.service.impl.AccountServiceImpl2">
        <property name="name" value="test"></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>
    <!-- 复杂类型的注入/集合类型的注入
        用于给list结构集合注入的标签:
            list array set
         用于给map结构注入的标签:
            map props
         结构相同,标签可以互换
    -->
    <bean id="accountService3" class="com.liuge.service.impl.AccountServiceImpl3">
        <property name="myStrs">
            <array>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </array>
        </property>
        <property name="myList">
            <list>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </list>
        </property>
        <property name="mySet">
            <set>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </set>
        </property>
        <property name="myMap">
            <map>
                <entry key="testA" value="aaa"></entry>
                <entry key="testB">
                    <value>bbb</value>
                </entry>
            </map>
        </property>
        <property name="myProps">
            <props>
                <prop key="testC">ccc</prop>
                <prop key="testD">ddd</prop>
            </props>
        </property>
    </bean>
    
    ```

    总结

    可以看到,spring的使用大量采用了配置的方式.日后的学习一定要好好学会配置.(想起了mybatis也是用的配置的方式).

  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
  • 原文地址:https://www.cnblogs.com/wushenjiang/p/12804089.html
Copyright © 2011-2022 走看看