JavaWeb框架-【Spring】-1-让你我如沐春风般滴框架!

本文介绍了Spring框架的基本概念,包括控制反转(IoC)、依赖注入(DI)和面向切面编程(AOP)等核心特性,并通过实例讲解了如何搭建开发环境、配置Spring XML以及实现单例模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

话说:

各位读者朋友,晚上好!看了前面几篇博客,也许有读者嘲笑,什么年代了,还在总结Hibernate、Struts2这些“陈旧”滴框架……

笔者总是相信,明历史,才能更好的看未来。不站在巨人的肩膀上,框架能发展到现在滴模样么。而且,从最原始的理解,一些设计思想非常经典,技术都是其次,思想最重要。

今天总结一下Sping。正如它滴名字,寓意着生机盎然,绿色环保,基业长青。也许用词不当,但是总能表达这是一个非常经典,至今仍旧魅力无限的框架!它的官网也是一片蓬勃之绿,简洁明快,干练大气。

目录:


一、整体架构
二、Spring概念及环境搭建
三、ApplicationContext与BeanFactory的区别
四、单例与”多例“在bean中的体现
五、如何用Java代码实现一个单例?
六、属性注入
七、总结


开发环境:

IntelliJ IDEA(2017.2.5)
Mavan web项目

一、整体架构

这里写图片描述

二、Spring概念及环境搭建

概念

IoC-Inversion of Control 控制反转
这是Spring世界中的关键字之一。简单说就是把我们之前每次new对象的控制权全权授予spring.xml配置文件中的bean去处理,我们只负责调用即可。

还有几个关键词,后续遇到再细说:DI——Dependency Injection 依赖注入 、AOP——Aspect-Oriented Programming面向切面编程
https://docs.spring.io/spring/docs/5.0.1.RELEASE/spring-framework-reference/core.html#beans

环境搭建

1)下载源码包

http://repo.spring.io/release/org/springframework/spring/

下载这个有啥用呢?里面有个docs文件夹,各种帮助文档,应有尽有!离线的,方便查看;还可以参考各种配置等;

2)导入.jar包
通过maven的pom.xml导入依赖,暂时可以只导入core,后续根据需要全部导入。

3)配置spring.xml
配置文件默认名:applicationContext.xml
我们修改为:spring.xml
随便修改,就是加载的时候,写清楚名字即可。核心是配置头部声明和bean。

4)如何获取bean?

a、定义JavaBean。这里Hello

<!--创建Hello Bean-->
    <!--name自定义-->
    <bean name="hello" class="com.hmc.spring.Hello" ></bean>

b、加载spring.xml配置文件

  ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");

c、获取指定的bean

//2 获取指定的bean
           Hello hello =(Hello) ac.getBean("hello");

d、调用bean中的方法

     //3 调用相应的属性和方法
            hello.say();

三、ApplicationContext与BeanFactory的区别

具体区别详见代码,代码中注解很详细
SpringTest

package com.hmc.spring;
import com.hmc.spring.action.BookAction;
import com.hmc.spring.dao.BookDao;
import com.hmc.spring.model.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * User:Meice
 * 2017/11/3
 */
public class SpringTest {

    //调用bean法一:
    @Test
     public void test01() {
        //1 加载spring.xml配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        //2 获取指定的bean
           Hello hello =(Hello) ac.getBean("hello");
        //3 调用相应的属性和方法
            hello.say();
        /**
         * 运行结果:
         * 十一月 03, 2017 3:49:40 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * Hello Spring!
         */

        /**
         * 总结:
         * 1、ApplicationContext是个接口,ClassPathXmlApplicationContext实现了这个接口;
         * 2、这里我们并没有new Hello这个类,但是却调用了里面的方法,原因就在于bean的作用。spring.xml中配置bean的时候,容器已经
         * 帮我们实例化了;
         * 3、这里就是典型的IoC-Inversion of Control 把new 对象的权利交给配置文件,而不是我们自己每次new;所以,以后的类如何实例化呢?
         * 就是在spring.mxl中配置即可.
         * 4、这里的目的不是说出这句话,是体会IoC这种思想。
         */
    }


    //调用bean法二:
    @Test
    public void test02() {
        BeanFactory factory = new ClassPathXmlApplicationContext("spring.xml");
         Hello hello =(Hello)  factory.getBean("hello");
         hello.say();

    }
    /**
     * 运行结果:
     * 十一月 03, 2017 4:14:03 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
     * 信息: Loading XML bean definitions from class path resource [spring.xml]
     * Hello Spring!
     */


    /**
     * 以上两种方式区别:
     * 1、ApplicationContext在应用服务器开启的时候,就把所有bean实例化;整体来看效率高,单次来看效率低;
     * 2、BeanFactory在getBean()的时候在实例化,单次效率高,整体效率低。
     * 3、类似的原理还有:Hibernate中获取单个对象的get()和load()方法;数据连接池;lazy修饰符(Scala)
     *
     */

    @Test
    public void test03() {
     ApplicationContext ac =   new ClassPathXmlApplicationContext("spring.xml");
     //得到bean的时候指定bean类型,避免类型转换
     Hello hello = ac.getBean("hello",Hello.class);
     hello.say();
    }
}

完整版的spring.xml

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

    <!--配置文件名默认applicationContext.xml 这里我们修改为spring.xml-->
<!--创建Hello Bean-->
    <!--name自定义-->
    <bean name="hello" class="com.hmc.spring.Hello" ></bean>
    <!--为了测试单例,这里利用之前的BookAction做演练-->
    <bean name="book" class="com.hmc.spring.model.Book" scope="singleton">
        <!--单属性注入-->
        <property name="name" value="《儒林外史》"></property>
        <!--多属性-数组注入-->
        <property name="names" value="《茶花女》,《瓦尔登湖》,《追风筝的人》,《红与黑》"></property>
        <property name="names2">
            <array>
                <value>《子夜》</value>
                <value>《茶馆》</value>
                <value>《丰乳肥臀》</value>
            </array>
        </property>
        <!--多属性List<>集合注入-->
        <property name="nameList" value="《格林童话》"></property>
        <property name="nameList2">
            <list>
                <value>《阿里巴巴与四十大盗》</value>
                <value>《安徒生童话》</value>
                <value>《伊索寓言》</value>
            </list>
        </property>
        <!--List<对象>属性注入-->
        <property name="bookList" ref="bk1">
        </property>

        <!--List<对象>多属性注入-->
        <property name="bookList2">
            <list>
                <ref bean="bk1"></ref>
                <ref bean="bk2"/>
                <ref bean="bk3"/>
            </list>
        </property>

        <!--Map属性注入-->
        <property name="nameMap">
            <map>
                <entry key="1" value-ref="bk1"></entry>
                <entry key="2" value-ref="bk3"></entry>
            </map>
        </property>

        <!--Set属性注入-->
        <property name="bookSet">
            <set>
                <ref bean="bk1"></ref>
                <ref bean="bk2"/>
                <ref bean="bk3"/>
            </set>
        </property>

    </bean>
    <bean name="bk1" class="com.hmc.spring.model.Book">
        <property name="name" value="《碧血剑》"></property>
    </bean>
    <bean name="bk2" class="com.hmc.spring.model.Book">
        <property name="name" value="《书剑恩仇录》"></property>
    </bean>
    <bean name="bk3" class="com.hmc.spring.model.Book">
        <property name="name" value="《连城诀》"></property>
    </bean>

    <bean name="bookDao" class="com.hmc.spring.dao.BookDao"></bean>
    <bean name="bookAction" class="com.hmc.spring.action.BookAction"></bean>

</beans>

四、单例与”多例“在bean中的体现

Spring里面通过scope属性来控制单例模式的。scope="singleton"表示单例(不论如何new,都是一个对象);scope = "prototype"表示多例。调用一次bean,就是一个全新的实例。

测试类SpringTest

package com.hmc.spring;
import com.hmc.spring.action.BookAction;
import com.hmc.spring.dao.BookDao;
import com.hmc.spring.model.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * User:Meice
 * 2017/11/3
 */
public class SpringTest {

    @Test
    public void test04(){
     ApplicationContext ac =   new ClassPathXmlApplicationContext("spring.xml");
        Hello hello1 = ac.getBean("hello",Hello.class);
        Hello hello2 = ac.getBean("hello",Hello.class);

        System.out.println(hello1==hello2);
        System.out.println(hello1.equals(hello2));

        /**
         * 运行结果:
         * 十一月 03, 2017 5:56:32 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * true
         */
        /**
         * 一个对象,我们两次getBean,按照之前思想,相当于new了两次,这两个对象自然不同
         * 但是呢,这里确实true?
         * 这就是singleton。 最直白的体现
         * scope属性控制单例和多例模式;默认是单例模式scope="singleton";多例是scope="prototype"
         */


    }

    @Test
    public void testBookAction(){
        //可以把获取ac定义为static{},避免每次获取,麻烦
    ApplicationContext ac =    new ClassPathXmlApplicationContext("spring.xml");
        BookDao bd = ac.getBean("bookDao",BookDao.class);

        Book bk1 = ac.getBean("book",Book.class);
        Book bk2 = ac.getBean("book",Book.class);
      //  bk1.setName("三国演义");
      //  bk2.setName("西游记");

        bd.add(bk1);
        bd.add(bk2);
        /**
         * 运行结果:
         * 十一月 03, 2017 6:14:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * 增加了《西游记》
         * 增加了《西游记》
         * 以上我明明获取了2个book对象(bean);并且赋值不一样,结果呢?后者覆盖了前者
         * 此时,配置文件保持默认,下来一个测试,修改配置文件scope属性为 prototype类型
         *
         *
         * 运行结果:
         * 十一月 03, 2017 6:19:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * 增加了《三国演义》
         * 增加了《西游记》
         * 这是框架通过scope属性方式来控制单例和多例;我们自己也可以写的。
         */


        /**
         * 有什么卵用呢?
         * 作用大了呢!存在即是合理的。
         * 比如Book这个bean,我们增加、修改等操作,都是不同的对象,就是和用多例;而BookAction基本不变,
         * 就用单例。
         * 生活中也有很多单例案例:比如你听歌曲,每次只能听一首歌,程序是不会允许你同时听两首歌曲的...
         * 还有很多类似案例,灰常有趣,读者可以自行查找相关资料奥!
         */


    }
 }

笔者在这里结合了上一篇博客图书管理系统中的例子,来演示了下单例、多例。
调动时候,要厘清关系。

这里写图片描述

以上仅仅为演示,所以真实情况并没有配置Struts2,其中:

BookAction

package com.hmc.spring.action;

import com.hmc.spring.dao.BookDao;
import com.hmc.spring.model.Book;

/**
 * User:Meice
 * 2017/11/3
 */
public class BookAction {

    BookDao bd = new BookDao();
    private Book book;
    public String  add() {
        bd.add(book);
        return "success";

    }

}

BookDao

package com.hmc.spring.dao;

import com.hmc.spring.model.Book;

/**
 * User:Meice
 * 2017/11/3
 */
public class BookDao {
    //定义一个方法增加图书
    public void add(Book book) {
        System.out.println("增加了《"+book.getName()+"》");
    }

}

Book

package com.hmc.spring.model;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * User:Meice
 * 2017/11/3
 */
public class Book {
    private String name;//单属性注入
    private String names[];//多属性数组注入-法一
    private String names2[];//多属性数组注入-法二
    private List<String> nameList;//List属性注入-法一
    private List<String> nameList2;//多属性List注入-法二
    private List<Book> bookList;//List<对象>属性注入
    private List<Book> bookList2;//List<对象>多属性注入
    private Map<Integer,Book> nameMap;//Map属性注入
    private Set<Book> bookSet;//Set属性注入




    /**
     * 属性注入本质是依赖set()方法的,所以
     * 属性都要生成或者自己写get() set()方法,注意name值等于setYy中的yy
     */

    public Set<Book> getBookSet() {
        return bookSet;
    }

    public void setBookSet(Set<Book> bookSet) {
        this.bookSet = bookSet;
    }

    public Map<Integer, Book> getNameMap() {
        return nameMap;
    }

    public void setNameMap(Map<Integer, Book> nameMap) {
        this.nameMap = nameMap;
    }

    public List<Book> getBookList2() {
        return bookList2;
    }

    public void setBookList2(List<Book> bookList2) {
        this.bookList2 = bookList2;
    }

    public List<Book> getBookList() {
        return bookList;
    }

    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }

    public List<String> getNameList2() {
        return nameList2;
    }

    public void setNameList2(List<String> nameList2) {
        this.nameList2 = nameList2;
    }

    public List<String> getNameList() {
        return nameList;
    }

    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    public String[] getNames2() {
        return names2;
    }

    public void setNames2(String[] names2) {
        this.names2 = names2;
    }

    public String[] getNames() {
        return names;
    }

    public void setNames(String[] names) {
        this.names = names;
    }

    public Book() {}
    public Book(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

   /* public void setName(String name) {
        this.name = name;
    }*/

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}

这里面之所以有这么多属性,是为第六个属性注入用的。

五、如何用Java代码实现一个单例?

单例设计模式就是一个实例。有什么用呢?应用非常广泛!比如播放音乐,每次只能播放一首歌,这就是典型的单例模式。
还有其他很多有趣应用,读者感兴趣,可以参考:
http://blog.youkuaiyun.com/tanyujing/article/details/14160941

这里我们自己来实现一个单例。

PlayMusic

package com.hmc.spring.singleton;

/**
 * User:Meice
 * 2017/11/3
 */
public class PlayMusic {
    //这一步是单例模式的核心-把构造方法私有化,外边就无法无休止的实例化
    private PlayMusic(){}
    private static PlayMusic pm;

    public  static PlayMusic getInstance() {
        if(pm == null) {
            pm = new PlayMusic();
        }
        return  pm;
    }

    public void play(String music) {
        System.out.println("演奏了音乐:"+music);
    }

    /**
     * 以前我们是这么处理年龄的
     */

  /*  private  int age;
    public void setAge(int age) {
        if (age>100){
            age = 80;
        }
    }*/


}

TestMusic

package com.hmc.spring.singleton;

/**
 * User:Meice
 * 2017/11/3
 */
public class TestMusic {
    public static void main(String[] args) {
      //  PlayMusic pm = new PlayMusic();
       // PlayMusic pm2 = new PlayMusic();

        PlayMusic pm = PlayMusic.getInstance();
        PlayMusic pm2 = PlayMusic.getInstance();

        System.out.println(pm == pm2);
        System.out.println("我是第一次实例化后的PlayMusic对象:"+pm);
        System.out.println("我是第二次实例化后的PlayMusic对象:"+pm2);
        pm.play("黑色的夜");
        pm.play("吻别");

        /**
         * 运行结果:
         * true
         * 我是第一次实例化后的PlayMusic对象:com.hmc.spring.singleton.PlayMusic@610455d6
         * 我是第二次实例化后的PlayMusic对象:com.hmc.spring.singleton.PlayMusic@610455d6
         * 演奏了音乐:黑色的夜
         * 演奏了音乐:吻别
         */
    }
}

以上可知,设计一个单例模式的关键是:

1、构造方法私有化,避免多次new;
2、给外界一个方法来实例化,类似ModelDriven的方式来进行判断,使其只能new一次。一旦new一次之后,再次new的时候,就直接返回已经new的对象。

六、属性注入

属性注入,顾名思义,就是为属性赋值。之前我们都是实例化对象后,通过set()方法来赋值的。这里全部转入到配置文件中初始化。复杂一点的是,属性可能是数组或集合。比如实体类之间有外键关联的时候,Employee和Department ;这个时候设置值就稍微复杂点。
Book
就不在赘述,和上面一样。

这里是完整版SpringTest

package com.hmc.spring;
import com.hmc.spring.action.BookAction;
import com.hmc.spring.dao.BookDao;
import com.hmc.spring.model.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * User:Meice
 * 2017/11/3
 */
public class SpringTest {

    //调用bean法一:
    @Test
     public void test01() {
        //1 加载spring.xml配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        //2 获取指定的bean
           Hello hello =(Hello) ac.getBean("hello");
        //3 调用相应的属性和方法
            hello.say();
        /**
         * 运行结果:
         * 十一月 03, 2017 3:49:40 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * Hello Spring!
         */

        /**
         * 总结:
         * 1、ApplicationContext是个接口,ClassPathXmlApplicationContext实现了这个接口;
         * 2、这里我们并没有new Hello这个类,但是却调用了里面的方法,原因就在于bean的作用。spring.xml中配置bean的时候,容器已经
         * 帮我们实例化了;
         * 3、这里就是典型的IoC-Inversion of Control 把new 对象的权利交给配置文件,而不是我们自己每次new;所以,以后的类如何实例化呢?
         * 就是在spring.mxl中配置即可.
         * 4、这里的目的不是说出这句话,是体会IoC这种思想。
         */
    }


    //调用bean法二:
    @Test
    public void test02() {
        BeanFactory factory = new ClassPathXmlApplicationContext("spring.xml");
         Hello hello =(Hello)  factory.getBean("hello");
         hello.say();

    }
    /**
     * 运行结果:
     * 十一月 03, 2017 4:14:03 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
     * 信息: Loading XML bean definitions from class path resource [spring.xml]
     * Hello Spring!
     */


    /**
     * 以上两种方式区别:
     * 1、ApplicationContext在应用服务器开启的时候,就把所有bean实例化;整体来看效率高,单次来看效率低;
     * 2、BeanFactory在getBean()的时候在实例化,单次效率高,整体效率低。
     * 3、类似的原理还有:Hibernate中获取单个对象的get()和load()方法;数据连接池;lazy修饰符(Scala)
     *
     */

    @Test
    public void test03() {
     ApplicationContext ac =   new ClassPathXmlApplicationContext("spring.xml");
     //得到bean的时候指定bean类型,避免类型转换
     Hello hello = ac.getBean("hello",Hello.class);
     hello.say();
    }


    @Test
    public void test04(){
     ApplicationContext ac =   new ClassPathXmlApplicationContext("spring.xml");
        Hello hello1 = ac.getBean("hello",Hello.class);
        Hello hello2 = ac.getBean("hello",Hello.class);

        System.out.println(hello1==hello2);
        System.out.println(hello1.equals(hello2));

        /**
         * 运行结果:
         * 十一月 03, 2017 5:56:32 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * true
         */
        /**
         * 一个对象,我们两次getBean,按照之前思想,相当于new了两次,这两个对象自然不同
         * 但是呢,这里确实true?
         * 这就是singleton。 最直白的体现
         * scope属性控制单例和多例模式;默认是单例模式scope="singleton";多例是scope="prototype"
         */


    }

    @Test
    public void testBookAction(){
        //可以把获取ac定义为static{},避免每次获取,麻烦
    ApplicationContext ac =    new ClassPathXmlApplicationContext("spring.xml");
        BookDao bd = ac.getBean("bookDao",BookDao.class);

        Book bk1 = ac.getBean("book",Book.class);
        Book bk2 = ac.getBean("book",Book.class);
      //  bk1.setName("三国演义");
      //  bk2.setName("西游记");

        bd.add(bk1);
        bd.add(bk2);
        /**
         * 运行结果:
         * 十一月 03, 2017 6:14:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * 增加了《西游记》
         * 增加了《西游记》
         * 以上我明明获取了2个book对象(bean);并且赋值不一样,结果呢?后者覆盖了前者
         * 此时,配置文件保持默认,下来一个测试,修改配置文件scope属性为 prototype类型
         *
         *
         * 运行结果:
         * 十一月 03, 2017 6:19:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * 增加了《三国演义》
         * 增加了《西游记》
         * 这是框架通过scope属性方式来控制单例和多例;我们自己也可以写的。
         */


        /**
         * 有什么卵用呢?
         * 作用大了呢!存在即是合理的。
         * 比如Book这个bean,我们增加、修改等操作,都是不同的对象,就是和用多例;而BookAction基本不变,
         * 就用单例。
         * 生活中也有很多单例案例:比如你听歌曲,每次只能听一首歌,程序是不会允许你同时听两首歌曲的...
         * 还有很多类似案例,灰常有趣,读者可以自行查找相关资料奥!
         */


    }
    private  static ApplicationContext ac;

    static {
      ac =  new ClassPathXmlApplicationContext("spring.xml");
    }


    //测试属性初始化:-单个属性注入
    @Test
    public  void test05(){
     Book book =   ac.getBean("book",Book.class);
        System.out.println(book);
        /**
         * <bean name="book" class="com.hmc.spring.model.Book" scope="singleton">
         *      <property name="name" value="《儒林外史》"></property>
         * </bean>
         *
         *
         *
         * 运行结果:
         * 十一月 03, 2017 9:11:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * Book{name='《儒林外史》
         */
    }

    /**
     * 需要注意:单个属性注入,本质是根据set()方法注入的,name要等于setYy的Yy小写后得yy;
     * 去掉set()方法,就会报错:ExceptionInInitializerError
     * Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'book' defined
     * in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.
     * beans.NotWritablePropertyException: Invalid property 'name' of bean class [com.hmc.spring.model.Book]:
     * Bean property 'name' is not writable or has an invalid setter method. Does the parameter type of the
     * setter match the return type of the getter?
     * 同理,如果属性名不符合setYy的规则,也是找不到的。如果你自己写set方法,就需要特别注意
     * 比如:setBookName的属性,配置的时候name="bookName",这样才能找到,而不是name
     */

    //测试多个属性注入-数组
    @Test
    public void test06(){
      Book book =  ac.getBean("book",Book.class);
        System.out.println(book.getNames()[0]);
        System.out.println(book.getNames().length);
        /**
         * 运行结果:
         * 十一月 03, 2017 11:19:31 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * 《茶花女》
         */
        System.out.println("---------------------------------------");
        for(String name : book.getNames()) {
            System.out.println(name);
        }

        /**
         * 十一月 03, 2017 11:22:29 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         《茶花女》
         4
         ---------------------------------------
         《茶花女》
         《瓦尔登湖》
         《追风筝的人》
         《红与黑》
         */
        System.out.println("---------------------------------------");
        for (String name:book.getNames2()){
            System.out.println(name);
        }
        /**
         ---------------------------------------
         《子夜》
         《茶馆》
         《丰乳肥臀》
         */
        /**
         * 规范的写法是用<array></array>
         */

    }



    //测试List属性注入
    @Test
    public void testList() {
        Book book =    ac.getBean("book",Book.class);
        System.out.println(book.getNameList());
        /**
         * 运行结果:
         * 十一月 03, 2017 11:35:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         * 信息: Loading XML bean definitions from class path resource [spring.xml]
         * [《格林童话》]
         */
        System.out.println("---------------------------------------");
        System.out.println(book.getNameList2());

        /**
         * 运行结果:
         * 十一月 04, 2017 12:06:32 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         [《格林童话》]
         ---------------------------------------
         [《阿里巴巴与四十大盗》, 《安徒生童话》, 《伊索寓言》]
         */

        System.out.println("---------------------------------------");
        for(String name:book.getNameList2()){
            System.out.println(name);
        }

        /**
         * 运行结果:
         * ---------------------------------------
         《阿里巴巴与四十大盗》
         《安徒生童话》
         《伊索寓言》
         */
        System.out.println("---------------------------------------");


        //测试List<对象>属性注入
        System.out.println(book.getBookList());
        /**
         * 运行结果:
         * ---------------------------------------
         [Book{name='《碧血剑》'}]
         */

        System.out.println("---------------------------------------");
        //测试List<对象>多属性注入
        System.out.println(book.getBookList2());
        /**
         * 运行结果:
         * ---------------------------------------
         [Book{name='《碧血剑》'}, Book{name='《书剑恩仇录》'}, Book{name='《连城诀》'}]
         */

    }



    //测试Map属性注入
    @Test
    public void testMap() {
        Book book = ac.getBean("book",Book.class);
        System.out.println(book.getNameMap());

        /**
         * 运行结果:
         * 十一月 04, 2017 12:38:39 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         {1=Book{name='《碧血剑》'}, 2=Book{name='《连城诀》'}}
         */


        System.out.println("---------------------------------------");
        //遍历一下
        Map<Integer,Book> mapBooks = book.getNameMap();
        Set<Integer> keys = mapBooks.keySet();
        Iterator<Integer> its = keys.iterator();
        while(its.hasNext()) {
          Integer key =  its.next();
        Book bk =  mapBooks.get(key);
            System.out.println(bk.getName());
        }

        /**
         * 运行结果:
         * 十一月 04, 2017 12:54:26 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         {1=Book{name='《碧血剑》'}, 2=Book{name='《连城诀》'}}
         ---------------------------------------
         《碧血剑》
         《连城诀》
         */

        System.out.println("---------------------------------------");
        //遍历法二:
       Set<Map.Entry<Integer,Book>>  setEntry =  mapBooks.entrySet();
        Iterator<Map.Entry<Integer,Book>> itn =  setEntry.iterator();
        while (itn.hasNext()) {
           Map.Entry<Integer,Book> enty = itn.next();
            System.out.println(enty.getValue().getName());
        }


    }


    //测试Set属性注入
    @Test
    public void testSet() {
        Book book =  ac.getBean("book",Book.class);
        System.out.println(book.getBookSet());
        /**
         * 运行结果:
         * 十一月 04, 2017 1:09:53 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         [Book{name='《碧血剑》'}, Book{name='《书剑恩仇录》'}, Book{name='《连城诀》'}]
         */

        System.out.println("---------------------------------------");
        //遍历取值
      Set<Book> books =   book.getBookSet();
      for(Book bk :books) {
          System.out.println(bk.getName());
      }

        /**
         * 运行结果:
         * 十一月 04, 2017 1:15:44 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
         信息: Loading XML bean definitions from class path resource [spring.xml]
         [Book{name='《碧血剑》'}, Book{name='《书剑恩仇录》'}, Book{name='《连城诀》'}]
         ---------------------------------------
         《碧血剑》
         《书剑恩仇录》
         《连城诀》
         */

    }

}

七、总结


1、有了IoC-控制反转,很少在用new了;

2、单例设计模式在Spring中的体现方式是bean的scope属性,分为singleton和prototype; 实际运用中我们可以自己写单例,来匹配业务需求;

3、属性注入为多类型的属性赋值提供了很好的配置方式。


好了,晚安!下期再会!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值