http://blog.csdn.net/yerenyuan_pku/article/details/69663685

Spring的概述

什么是Spring

据度娘所载:

Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。

Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架

为什么说Spring是一个一站式的轻量级开源框架呢?EE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。

  • WEB层:SpringMVC
  • 业务层:Spring的IoC
  • 持久层:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久层框架)

从上面的简要介绍中,我们要知道Spring的核心有两部分:

  • IoC:控制反转。 
    举例来说,在之前的操作中,比方说有一个类,我们想要调用类里面的方法(不是静态方法),就要创建类的对象,使用对象调用方法实现。对于Spring来说,Spring创建对象的过程,不是在代码里面实现的,而是交给Spring来进行配置实现的。
  • AOP:面向切面编程。 
    之前,讲Struts2框架的拦截器时,我们就已稍微讲了一下,在Spring学习过程中,我们会着重来讲它。但是本文并不会过多阐述它,下文再讲。

为什么Spring

  • 方便解耦,简化开发。 
    Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。
  • AOP编程的支持 
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
  • 声明式事务的支持 
    只需要通过配置就可以完成对事务的管理,而无须手动编程。
  • 方便程序的测试 
    Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  • 方便集成各种优秀的框架 
    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
  • 降低JavaEE API的使用难度 
    Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

Spring的版本

我这儿使用的Spring的版本是spring-framework-4.2.4.RELEASE。

Spring的入门案例

IOC的底层实现原理

IOC:Inversion of Control,控制反转。指的是对象的创建权反转(交给)给Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了。对象创建的控制权不是“使用者”,而是“框架”或者“容器”。 
用更通俗的话来说,IOC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。其底层实现原理是XML配置文件+SAX解析+工厂设计模式。 
就拿持久层(也即dao(data access object,数据访问对象)层)的开发来说,官方推荐做法是先创建一个接口,然后再创建接口对应的实现类。 
先创建一个Userdao接口

public interface UserDao {
public void add();
}

再创建Userdao接口的UserDaoImpl实现类

public class UserDaoImpl implements UserDao {
public void add() {
balabala......
}
}

接着我们在service层调用dao层,核心代码如下:

// 接口 实例变量 = new 实现类
UserDao dao = new UserDaoImpl();
dao.add();

可发现缺点:service层和dao层耦合度太高了。解决方法是使用工厂模式进行解耦合操作。 
创建一个工厂类,在工厂类中提供一个方法,返回实现类的对象。

public class Factory {
// 提供返回实现类对象的方法
public static UserDao getUserDaoImpl() {
return new UserDaoImpl();
}
}
  • 1

然后在service层调用dao层的核心代码就变为:

UserDao dao = Factory.getUserDaoImpl();
dao.add();

如若这样做,会发现又产生了一个缺点:service层和工厂类又耦合了。所以使用工厂模式进行解耦合也只是一种权宜之计。下面我就来简单讲讲Spring IOC的底层实现原理:

  • 配置文件中可能会有如下配置信息:

    <bean id="userDaoImpl" class="cn.itcast.dao.impl.UserDaoImpl" />
  • 也是要创建一个工厂类,在工厂类中提供一个返回实现类对象的方法,但并不是直接new实现类,而是使用SAX解析配置文件,根据标签bean中的id属性值得到对应的class属性值,使用反射创建实现类对象。

    public class Factory {
    public static UserDao getUserDaoImpl() {
    // 1.使用SAX解析得到配置文件内容
    // 直接根据id值userDaoImpl得到class属性值
    String classvalue = "class属性值";
    // 2.使用反射得到对象
    Class clazz = Class.forName(classvalue);
    UserDaoImpl userDaoImpl = (UserDaoImpl)lazz.newInstance();
    return userDaoImpl;
    }
    }
    • 1

面向对象设计的七大原则

这里我稍微讲一下面向对象设计的七大原则,不必强记,重在理解。

  1. 单一职责原则(Single Responsibility Principle):每一个类应该专注于做一件事情。
  2. 里氏替换原则(Liskov Substitution Principle):超类存在的地方,子类是可以替换的。
  3. 依赖倒置原则(Dependence Inversion Principle):实现尽量依赖抽象,不依赖具体实现。
  4. 接口隔离原则(Interface Segregation Principle):应当为客户端提供尽可能小的单独的接口,而不是提供大的总的接口。
  5. 迪米特法则(Law Of Demeter):又叫最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用。
  6. 开闭原则(Open Close Principle):面向扩展开放,面向修改关闭。
  7. 组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP):尽量使用组合/聚合达到复用,尽量少用继承。原则: 一个类中有另一个类的对象。

Spring的IOC入门

步骤一:下载Spring的开发包

Spring的官网是http://spring.io。Spring的开发包的下载地址是http://repo.springsource.org/libs-release-local/org/springframework/spring,上面说过,我下载的是spring-framework-4.2.4.RELEASE。解压缩之后,可发现Spring开发包的目录结构如下: 

  • docs:API和开发规范
  • libs:Jar包和源码
  • schema:约束

步骤二:创建Web项目,引入Spring的开发包

从下图可知: 

由于我们只是初次入门Spring,所以也只是使用Spring的基本功能,所以需要使用到下面的这4个Jar包: 
 
除此之外,还要导入Spring支持的日志Jar包: 

步骤三:编写相关的类,在类中创建方法

在src目录下创建一个cn.itcast.ioc包,并在该包下创建一个User类。

public class User {
public void add() {
System.out.println("add.................");
}
}
  • 1

步骤三:创建Spring配置文件

注意:Spring配置文件的名称和位置没有固定要求,一般建议把该文件放到src下面,名称可随便写,官方建议写成applicationContext.xml。但我觉得这个文件名称太长了,所以决定写为bean1.xml。然后我们还需要在配置文件中引入约束,Spring学习阶段的约束是schema约束。那么问题来了,这个约束又该怎么写呢?可参考docs\spring-framework-reference\html目录下的xsd-configuration.html文件,在其内容最后找到如下内容:

<?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="foo" class="x.y.Foo">
<meta key="cacheName" value="foo"/>
<property name="name" value="Rick"/>
</bean> </beans>
  • 1

然后将其复制黏贴到配置文件bean1.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>
  • 1

步骤四:在配置文件中配置对象的创建

<!-- 1.配置user对象的创建 -->
<bean id="user" class="cn.itcast.ioc.User"></bean>

步骤五:编写测试程序

我们要在Spring中写代码来实现获取bean1.xml文件中配置的对象(该段代码不要求重点掌握,只是用在测试中而已)。这段代码主要用来解析Spring配置文件得到对象,但这个过程不需要我们写代码实现,Spring封装了一个对象帮我们进行了这些操作,这个对象叫ApplicationContext,它就能实现这个功能。 
在cn.itcast.ioc包下创建一个TestIOC单元测试类,如下:

public class TestIOC {

    // 得到配置的user对象
@Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml"); // classpath:类路径,src目录下的文件最终要编译到类路径下
// 2.根据配置文件的id得到user对象
User user = (User) context.getBean("user");
System.out.println(user);
user.add();
}
}
  • 1

注意:classpath为类路径,src目录下的文件最终要编译到类路径下

Spring的bean管理

通俗一点说,Spring的bean管理即指创建对象时不需要new操作代码实现,而是交给Spring进行配置完成。 
Spring进行bean管理有两种方式:

  1. 使用配置文件方式实现
  2. 使用注解方式实现

本文将重点放在第一种方式上,后一种方式后面会讲。

Spring实例化bean的三种方式

使用无参构造(重点)

创建对象时候,调用类里面的无参数的构造方法实现。那么Spring配置文件中又该怎样写呢?基本类似于如下写法:

<!-- 1.配置user对象的创建 -->
<bean id="user" class="cn.itcast.ioc.User"></bean>

使用静态工厂(了解)

创建一个工厂类,在工厂类中提供一个静态的方法,这个方法返回类的对象;调用工厂类的方法时候,直接使用类名.方法名称即可以调用。下面举例来说明。 
在src目录下创建一个cn.itcast.bean包,并在该包下创建一个Bean1类。

public class Bean1 {

    public void bean1() {
System.out.println("bean1..........");
} }
  • 1

然后在该包下创建一个Bean1Factory工厂类。

public class Bean1Factory {

    // 静态方法
public static Bean1 getBean1() {
return new Bean1();
} }
  • 1

接着Spring配置文件中应向下面这样配置:

<!-- 2.使用静态工厂创建对象 -->
<bean id="bean1" class="cn.itcast.bean.Bean1Factory" factory-method="getBean1"></bean>

最后在该包下创建一个TestIOC单元测试类。

public class TestIOC {

    @Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
// 2.根据配置文件的id得到user对象
Bean1 bean1 = (Bean1) context.getBean("bean1");
System.out.println(bean1);
}
}
  • 1

使用实例工厂(了解)

创建一个工厂类,在工厂类里面提供一个普通的方法,这个方法返回类对象;调用工厂类的方法时候,创建工厂类对象,使用对象调用方法即可。下面也举例来说明。 
在src目录下的cn.itcast.bean包下创建一个Bean2类。

public class Bean2 {

    public void bean2() {
System.out.println("bean2..........");
} }
  • 1

然后在该包下创建一个Bean2Factory工厂类。

public class Bean2Factory {

    public Bean2 getBean2() {
return new Bean2();
} }
  • 1
  • 2

接着Spring配置文件中应向下面这样配置:

<!-- 3.使用实例工厂创建对象 -->
<!-- 3.1先创建工厂对象 -->
<bean id="bean2Factory" class="cn.itcast.bean.Bean2Factory"></bean>
<!-- 3.2再使用工厂对象创建bean2对象 -->
<bean id="bean2" factory-bean="bean2Factory" factory-method="getBean2"></bean>
  • 1
  • 2

最后将TestIOC单元测试类的代码修改为:

public class TestIOC {

    @Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
// 2.根据配置文件的id得到user对象
Bean2 bean2 = (Bean2) context.getBean("bean2");
System.out.println(bean2);
}
}
  • 1

Spring配置文件中bean标签常用的属性

Spring配置文件中bean标签常用的属性有以下四种:

  1. id属性:根据id属性值得到配置对象。 
    在Spring配置文件中会有多个bean标签,但它们的id属性值是不能相同的。Bean起名字时,在约束中采用的是ID约束——唯一,而且名字必须以字母开始,可以使用字母、数字、连字符、下划线、句号、冒号等,但id属性值不能有特殊符号。
  2. class属性:要创建对象的类的全路径。
  3. scope属性:bean的作用范围。 
    scope属性共有以下5个属性:

    • singleton:创建的对象是单例的,也是scope属性的默认值。 
      下面我来举例说明它。将TestIOC单元测试类的代码修改为:

      public class TestIOC {
      
          // 得到配置的user对象
      @Test
      public void demo1() {
      // 1.加载Spring配置文件,把配置文件中的对象进行创建
      ApplicationContext context =
      new ClassPathXmlApplicationContext("bean1.xml");
      // 2.根据配置文件的id得到user对象
      User user1 = (User) context.getBean("user");
      User user2 = (User) context.getBean("user");
      System.out.println(user1);
      System.out.println(user2);
      }
      }
      • 1

      单元测试以上方法,一切就尽在不言中。其实,此时Spring配置文件中有关如下bean的配置:

      <bean id="user" class="cn.itcast.ioc.User"></bean>
      • 1
      • 1

      就相当于:

      <bean id="user" class="cn.itcast.ioc.User" scope="singleton"></bean>
      • 1
      • 1
    • prototype:创建的对象是多实例的。 
      也可举例来说明它。将Spring配置文件中有关如下bean的配置:

      <bean id="user" class="cn.itcast.ioc.User"></bean>
      • 1
      • 1

      修改为:

      <bean id="user" class="cn.itcast.ioc.User" scope="prototype"></bean>
      • 1
      • 1

      测试单元测试类的方法就能明白了。

    • globalSession:用在单点登录(即SSO,single sign on)上。
  4. name属性:name属性的功能和id属性是一样的。name属性和id属性区别是:在id属性值里面不能有特殊符号,在name属性值里面可以添加特殊符号。

bean的生命周期的配置

通过配置<bean>标签上的init-method作为bean的初始化的时候执行的方法,配置destroy-method作为bean的销毁的时候执行的方法。销毁方法想要执行,需要是单例创建的Bean而且在工厂关闭的时候,Bean才会被销毁。

Spring中Bean的属性注入

实际上,有关Bean的属性注入共有三种方式,下面我分别加以简单的说明:

  1. set方法注入 
    用代码可表示如下:

    public class Book {
    
        private String bookname;
    
        public void setBookname(String bookname) {
    this.bookname = bookname;
    } } Book book = new Book();
    book.setBookName("Java编程思想");
    • 1
  2. 有参数构造注入 
    用代码可表示如下:

    public class Book {
    
        private String bookname;
    
        public Book(String bookname) {
    this.bookname = bookname;
    } } Book book = new Book("代码大全");
    • 1
  3. 接口注入 
    先编写一个接口:

    public interface Dao {
    public void add(String name);
    }

    再编写这个接口的实现类:

    public class DaoImpl implements Dao {
    private String name; public void add(String name) {
    this.name = name;
    }
    }
    • 1

但在Spring框架里面,只支持前两种方式,即set方法注入和有参数构造注入。下面我来举例分别演示。

构造方法的方式注入属性

在src目录下创建一个cn.itcast.property包,并在该包下编写一个Book实体类。

public class Book {

    private String bookname;

    public Book(String bookname) {
this.bookname = bookname;
} public void testBook() {
System.out.println("book.............." + bookname);
} }
  • 1

接着在Spring配置文件中对以上JavaBean添加如下配置:

<!-- 4.使用有参数的构造注入属性 -->
<bean id="book" class="cn.itcast.property.Book">
<!-- 使用标签,name:为属性的名字;value:为属性的值 -->
<constructor-arg name="bookname" value="beautifulMan_美美侠"></constructor-arg>
</bean>

最后在该包下编写一个TestIOC单元测试类:

public class TestIOC {

    @Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml"); Book book = (Book) context.getBean("book");
book.testBook();
}
}
  • 1

自己自行测试去吧!

set方法的方式注入属性

我们同样在cn.itcast.property包下编写一个Person实体类,在类中定义属性,并生成set方法。

public class Person {

    // 1.定义一个属性
private String username; // 2.生成这个属性的set方法
public void setUsername(String username) {
this.username = username;
} public void testperson() {
System.out.println("person.............." + username);
} }
  • 1

然后在Spring配置文件中,使用bean标签创建对象,在bean标签里面使用property标签注入属性。即在Spring配置文件中对以上JavaBean添加如下配置,

<!-- 5.使用set方法进行注入属性 -->
<bean id="person" class="cn.itcast.property.Person">
<!--
使用property标签注入属性值
name:类属性名称
value属性:往属性中注入的值
-->
<property name="username" value="李阿昀"></property>
</bean>
  • 1

最后将TestIOC单元测试类的代码修改为:

public class TestIOC {

    @Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml"); Person person = (Person)context.getBean("person");
person.testperson();
}
}
  • 1

自己自行测试去吧!

Spring的属性注入:对象类型的注入

在实际开发中,我们要提交表单到action里面去,然后在action里面调用service层的方法,接着在service层里面调用dao层的方法。在这里,我假设在service层里面调用dao层的方法,所以需要在servcie层里面创建dao层的对象实现调用。 
先在src目录下创建一个cn.itcast.dao包,并在该包下编写一个UserDao类。

public class UserDao {

    public void add() {
System.out.println("dao................");
}
}
  • 1

然后在src目录下再创建一个cn.itcast.service包,并在该包下编写一个UserService类。

public class UserService {

    public void add() {
System.out.println("service.........");
// 调用dao
balabala......
} }
  • 1

如果我们使用最原始的方式在service层里面调用dao层的方法,那么UserService类中add()方法应这样写:

public void add() {
System.out.println("service.........");
// 原始方式,调用dao
UserDao dao = new UserDao();
dao.add();
}
  • 1

在Spring里面,我们就应该这么玩了。我们的最终目的是在service层里面得到dao层对象。所以步骤为:

  1. 第一步,让dao作为service的一个属性。

    // 1.让dao作为service的一个属性
    private UserDao userDao;
  2. 第二步,生成dao属性的set方法。

    // 2.生成dao属性的set方法
    public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
    }

    这时,UserService类的代码就变成:

    public class UserService {
    
        // 1.让dao作为service的一个属性
    private UserDao userDao; // 2.生成dao属性的set方法
    public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
    } public void add() {
    System.out.println("service.........");
    userDao.add();
    } }
    • 1
  3. 在Spring配置文件中进行配置和注入。

    <!-- 6.注入对象的属性 -->
    <!-- 6.1先创建dao对象 -->
    <bean id="userDao" class="cn.itcast.dao.UserDao"></bean>
    <!-- 6.2再创建service对象 -->
    <bean id="userService" class="cn.itcast.service.UserService">
    <!-- 在servcie里面注入userDao属性
    name属性:service对象里面的userDao属性的名称
    注入dao对象,不能写value属性,要写ref属性:dao配置的bean的id值
    -->
    <property name="userDao" ref="userDao"></property>
    </bean>
    • 1

名称空间p的属性注入方式——Spring2.x版本后提供的方式

在src目录下创建一个cn.itcast.propertydemo包,并在该包下编写一个Orders实体类。

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} public void testorders() {
System.out.println("orders................" + oname);
}
}
  • 1

接下来我们需要在Spring核心配置文件中的schema约束位置定义p名称空间。

xmlns:p="http://www.springframework.org/schema/p"
  • 1
  • 1

紧接着,我们需要在Spring核心配置文件中添加如下配置:

<!-- 7.p(property,属性)名称空间的注入 -->
<bean id="orders" class="cn.itcast.propertydemo.Orders" p:oname="去你妈的!!!"></bean>
  • 1
  • 2
  • 1
  • 2

最后将cn.itcast.property包下的TestIOC单元测试类的代码修改为:

public class TestIOC {
@Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml"); Orders orders = (Orders)context.getBean("orders");
orders.testorders();
}
}
  • 1

测试即可。 
结论——使用p名称空间:

  • 普通属性:p:属性名称=”…”
  • 对象类型的属性:p:属性名称-ref=”…”

注入复杂属性

注入数组类型的属性

将cn.itcast.propertydemo包下的Orders类的代码修改为:

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} // 1.数组类型的属性
private String[] arrays;
public void setArrays(String[] arrays) {
this.arrays = arrays;
} public void testorders() {
// System.out.println("orders................" + oname);
System.out.println("数组:" + Arrays.toString(arrays));
}
}
  • 1

然后需要在Spring核心配置文件中添加如下配置:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- 数组类型 -->
<property name="arrays"> <!-- 注入属性 -->
<list>
<value>叶子</value>
<value>liayun</value>
<value>杰哥</value>
</list>
</property>
</bean>
  • 1

最后将cn.itcast.property包下的TestIOC单元测试类的代码修改为:

public class TestIOC {
@Test
public void demo1() {
// 1.加载Spring配置文件,把配置文件中的对象进行创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
Orders orders = (Orders)context.getBean("orders");
orders.testorders();
}
}
  • 1

测试即可。

注入List集合类型的属性

将cn.itcast.propertydemo包下的Orders类的代码修改为:

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} // 2.list类型的属性
private List<String> list;
public void setList(List<String> list) {
this.list = list;
} public void testorders() {
// System.out.println("orders................" + oname);
System.out.println("list:" + list);
}
}
  • 1

然后需要在Spring核心配置文件中添加如下配置:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- list类型 -->
<property name="list">
<list>
<value>叶子</value>
<value>李昀玲</value>
<value>杰哥</value>
</list>
</property>
</bean>
  • 1

cn.itcast.property包下的TestIOC单元测试类的代码勿须修改,直接测试即可。

注入Set集合类型的属性

将cn.itcast.propertydemo包下的Orders类的代码修改为:

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} // 3.set类型的属性
private Set<String> keyset;
public void setKeyset(Set<String> keyset) {
this.keyset = keyset;
} public void testorders() {
// System.out.println("orders................" + oname);
System.out.println("set:" + keyset);
}
}
  • 1

然后需要在Spring核心配置文件中添加如下配置:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- set类型 -->
<property name="keyset">
<set>
<value>蝙蝠侠</value>
<value>钢铁侠</value>
<value>美美侠</value>
</set>
</property>
</bean>
  • 1

其实,以上配置也可以写为:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- set类型 -->
<property name="keyset">
<list>
<value>蝙蝠侠</value>
<value>钢铁侠</value>
<value>美美侠</value>
</list>
</property>
</bean>
  • 1

cn.itcast.property包下的TestIOC单元测试类的代码勿须修改,直接测试即可。

注入Map集合类型的属性

将cn.itcast.propertydemo包下的Orders类的代码修改为:

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} // 4.map类型
private Map<String, String> map;
public void setMap(Map<String, String> map) {
this.map = map;
} public void testorders() {
// System.out.println("orders................" + oname);
System.out.println("map:" + map);
}
}
  • 1

然后需要在Spring核心配置文件中添加如下配置:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- map类型 -->
<property name="map">
<map>
<entry key="username" value="潘金莲"></entry>
<entry key="password" value="1314"></entry>
<entry key="address" value="明初"></entry>
</map>
</property>
</bean>
  • 1

cn.itcast.property包下的TestIOC单元测试类的代码勿须修改,直接测试即可。

注入Properties类型的属性

将cn.itcast.propertydemo包下的Orders类的代码修改为:

public class Orders {

    private String oname;

    public void setOname(String oname) {
this.oname = oname;
} // 5.properties
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
} public void testorders() {
// System.out.println("orders................" + oname);
System.out.println("properties:" + properties);
}
}
  • 1

然后需要在Spring核心配置文件中添加如下配置:

<bean id="orders" class="cn.itcast.propertydemo.Orders"> <!-- 创建对象 -->
<!-- properties类型 -->
<property name="properties">
<props>
<prop key="name">宫本一郎</prop>
<prop key="address">日本</prop>
</props>
</property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

cn.itcast.property包下的TestIOC单元测试类的代码勿须修改,直接测试即可。

IoC和DI的区别

  • IoC:控制反转,即把对象的创建交给Spring进行管理。所以Spring IoC容器是用来创建对象,管理依赖关系的。
  • DI(Dependency Injection):依赖注入,即在创建对象的过程中,向类里面的属性中设置值。
  • IoC和DI的关系:依赖注入不能单独存在,须在控制反转基础之上完成,用更通俗点的话来说,就是注入类里面的属性值,不能直接注入,须创建类的对象再完成注入。

Spring中的工厂

ApplicationContext

ApplicationContext接口有两个实现类,如下图: 

  • ClassPathXmlApplicationContext:加载的是类路径下的Spring配置文件
  • FileSystemXmlApplicationContext:加载的是本地磁盘下的Spring配置文件

BeanFactory

下面应该是BeanFactory类的继承体系图吧! 

稍微了解一下就好,这个类在实际开发中我们并不需要用到。

ApplicationContext和BeanFactory的区别

虽然使用这两个对象都可以加载Spring的配置文件,并创建配置文件中的对象。但他俩还是有区别的,最主要的区别是:

  • 使用applicationContext操作时,可把Spring里面的配置文件中的对象都进行创建。
  • 使用BeanFactory对象操作时,在调用getBean方法的时候进行对象的创建。

Spring整合Web项目的底层原理

在实际的开发中,我们一般会使用SSH(即Struts2、Spring、Hibernate)进行开发,然后创建Spring的配置文件,使用applicationContext对象加载配置文件,继而创建对象。在真正的开发中,我们一般不会直接写applicationContext代码加载配置文件。

Spring整合Web项目的思想

在服务器启动的时候,加载Spring配置文件,并创建对象。

Spring整合Web项目的底层原理

Spring整合Web项目用到以下两个技术:

  • 使用ServletContext对象(在服务器启动时创建)
  • 使用监听器

在服务器启动的时候,每个项目都会创建一个ServletContext对象,而且每个项目只有一个ServletContext对象。在ServletContext对象创建的时候,使用监听器可以监听到其创建。当我们监听到ServletContext对象创建时,Spring就会帮我们做一件事情——加载Spring配置文件,并把配置文件中的对象进行创建,对象创建之后,放到ServletContext域里面去,最终我们要使用创建的对象,可从ServletContext域里面获取出来。

(转)Spring的概述的更多相关文章

  1. Spring Integration概述

    1.   Spring Integration概述 1.1     背景 Spring框架的一个重要主题是控制反转.从广义上来说,Spring处理其上下文中管理的组件的职责.只要组件减轻了职责,它们同 ...

  2. Spring Cloud 概述

    1. Spring Cloud 引言 首先我们打开spring 的官网:https://spring.io/ 我们会看到这样一张图片 这个图片告诉我们,开发我们的应用程序就像盖楼一样, 首先我们需要搭 ...

  3. 微服务与Spring Cloud概述

    微服务与Spring Cloud随着互联网的快速发展, 云计算近十年也得到蓬勃发展, 企业的IT环境和IT架构也逐渐在发生变革,从过去的单体应用架构发展为至今广泛流行的微服务架构. 微服务是一种架构风 ...

  4. Spring IOC 概述

    Spring IOC 概述 IOC(Inversion of Control) 控制反转,也叫 DI(D_ependency injection_) 依赖注入.是一种设计思想.不过我并不同意所谓反转的 ...

  5. 1.Spring 框架概述

    目录 Spring 框架概述 1 我们所说的 "Spring "是什么意思 2. Spring和Spring框架的历史 3. 设计理念 4.反馈和贡献 5.开始使用 Spring ...

  6. Spring JDBC概述

    1.jdbc 概述 Spring JDBC是Spring框架的持久层子框架.用于对数据库的操作(增删改查). 而JdbcTemplate它是spring jdbc子框架中提供的一个操作类,用于对原始J ...

  7. 0000 - Spring Cloud 概述

    1.概述 Spring Cloud是一系列框架的有序集合,它利用Spring Boot的开发便利性简化了分布式系统的开发,比如服务发现.服务网关.服务路由.链路追踪等.Spring Cloud并不重复 ...

  8. (一) Spring基础概述

    1.历史 第一阶段:xml配置 在Spring1.x时代,使用Spring开发满眼都是xml配置的Bean,随着项目的扩大,我们需要把xml配置文件分布放到不同配置文件中,需要频繁的在开发的类和配置文 ...

  9. spring DefaultListableBeanFactory 概述

                 有人说,DefaultListableBeanFactory是spring的发动机,其实重要性不为过.TA的整体类图如下:     这里先概述接口部分:   BeanFact ...

随机推荐

  1. python批量读取txt文件为DataFrame

    我们有时候会批量处理同一个文件夹下的文件,并且希望读取到一个文件里面便于我们计算操作.比方我有下图一系列的txt文件,我该如何把它们写入一个txt文件中并且读取为DataFrame格式呢? 首先我们要 ...

  2. [Java]手动编译Java

    1.安装JDK 2.编写 Example.java 程序放到C 盘 public class Example { public static void main(string[] args) { sy ...

  3. 深入理解dispatch_sync

    关于GCD的基础知识,之前写过一篇博客,详见GCD基础知识.虽然之前已经梳理过了,但对很多知识点的理解仍然不够透彻…写这篇博客的原因是在阅读AFNetworking代码时遇到一些奇怪的代码. 如下: ...

  4. June Challenge 2017

    A Good Set 分析:水题,选奇数即可 #include "iostream" #include "cstdio" #include "cstr ...

  5. 收集几个Android CalendarView非常用属性

    android:dateTextAppearance 设置日历View在日历表格中的字体皮肤;android:firstDayOfWeek 指定日历第一个星期的第一天,在日历中横向所在位置,从右边向左 ...

  6. CMake 手册详解(二十)

    SirDigit CMake 手册详解(二十) CMD#51: list 列表操作命令. list(LENGTH <list> <output variable>) list( ...

  7. mtr和nmap命令

    mtr mtr是一个网络连通性判断工具,它可以结合ping nslookup tracert 来判断网络的相关特性. [root@10.10.90.97 ~]# mtr -h usage: mtr [ ...

  8. Unity3D模型制作规范[转]

    本文提到的所有数字模型制作,全部是用3D MAX建立的模型,即使是不同的驱动引擎,对模型的要求基本是相同的.当一个VR模型制作完成时,它所包含的基本内容包括:场景尺寸.单位,模型归类塌陷.命名.节点编 ...

  9. HDU5213(容斥定理+莫队算法)

    传送门 题意 给出n个数和幸运数k,m次询问,每次询问[l1,r1]和[l2,r2]有多少对数满足x+y=k,x∈[l1,r1],y∈[l2,r2] 分析 看到m只有3e4,可以考虑\(m\sqrt{ ...

  10. 2017.11.7~8模拟测试总结---暨NOIP2017考前对策

    最后两天了,第三天就是NOIP2017--Day1了. 刚刚考完了这个学期从开学以来的最后一场模拟赛了.首先要对于这场模拟赛做一次深刻的反思. 考完才猛地惊叹这是最后一场模拟赛了,然而题目并不难,也保 ...