SpringIOC

Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。

步骤:
A. 启动spring容器

  1. 在类路径下寻找配置文件来实例化容器
     ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});

可以在整个类路径中寻找xml文件
* 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
* classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。
*

  1. 在文件系统路径下寻找配置文件来实例化容器
 ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{"d:\\beans.xml"});

Spring的配置文件可以指定多个,可以通过String数组传入。
注:经常用第一种方法启动容器

B. 从spring容器中提取对象

别名

<beans>
    <alias name="person" alias="p"/>
    <bean name="person" class="cn.itcast.aliasspring.Person"/>
</beans>

通过这样的配置,可以达到在一个地方命名,在多个地方使用不同的名字的效果。
这里写图片描述

这里写图片描述

这里写图片描述

junit测试结果:
这里写图片描述

Spring容器内部对象的创建

使用类构造器实例化(默认无参数)

这里写图片描述

使用静态工厂方法实例化(简单工厂模式)

这里写图片描述

这里写图片描述

这里写图片描述

初始化bean时机

Spring默认在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext会自动创建并配置所有的singleton bean.通常情况下这是件好事。因为这样在配置中有任何错误能立即发现。
Lazy-init=”true or false”
Lazy-init 为false,spring容器将在启动的时候报错(比较好的一种方式)
Lazy-init 为true,spring容器将在调用该类的时候出错。
这里写图片描述

Bean的作用域

singleton(默认值)

在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:

 <bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/>

如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:

<beans default-lazy-init="true“ ...> 

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

prototype

允许bean可以被多次实例化(使用一次就创建一个实例) . Spring不能对一个prototype bean的整个生命周期负责.这就意味着清楚prototype作用域的对象并释放任何prototype bean所持有的昂贵资源都是客户端的责任。

这里写图片描述

这里写图片描述

这里写图片描述

Request

这里写图片描述

Session

这里写图片描述

Global session

这里写图片描述

指定Bean的初始化方法和销毁方法

这里写图片描述

这里写图片描述

这里写图片描述

依赖注入(DI)

使用构造器注入

使用xml的注入方式
A.  通过参数的顺序
<constructor-arg index="0">
      <value>张三</value>
</constructor-arg>
<constructor-arg index="1">
       <value>56</value>
 </constructor-arg> 
B.  通过参数的类型
<constructor-arg type="java.lang.Integer">
              <value>56</value>
       </constructor-arg>
       <constructor-arg type="java.lang.String">
              <value>张三</value>
       </constructor-arg>

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

使用属性setting方法进行注入

使用xml的注入方式:
A. 简单Bean的注入
简单Bean包括两种类型:包装类型和String

<bean id="personService"   class="com.itcast.bean.impl.PersonServiceImpl">
<!-- 基本类型,string类型 -->
<property name="age" value="20"></property>
<property name="name" value="张无忌"></property>                        </bean>

B. 引用其他Bean

<bean id="person" class="com.itcast.bean.Person" />
 <bean id="personService"  class="com.itcast.bean.impl.PersonServiceImpl">
 <property name="person" ref="person" />
</bean>

装配list集合

这里写图片描述

装配set集合

这里写图片描述

装配map

<property name="maps">
             <map>
                  <entry key="01">
                          <value>map01</value>
                  </entry>
                  <entry key="02">
                          <value>map02</value>
                  </entry>  
             </map>
</property>

map中的<entry>的数值和<list>以及<set>的一样,可以使任何有效的属性元
素,需要注意的是key值必须是String的。

装配Properties

<property name="props">
           <props>
             <prop key="01">prop1</prop>
             <prop key="02">prop2</prop>
           </props>
        </property>  

示例

package cn.itcast.spring0909.di.xml.set;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Person {
    private Long pid;//包装类型
    private String pname;//String类型
    private Student student;//引用类型

    private List lists;

    private Set sets;

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public List getLists() {
        return lists;
    }

    public void setLists(List lists) {
        this.lists = lists;
    }

    public Set getSets() {
        return sets;
    }

    public void setSets(Set sets) {
        this.sets = sets;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    private Map map;

    private Properties properties;
}
<?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-2.5.xsd">
    <bean id="person" class="cn.itcast.spring0909.di.xml.set.Person">
        <!-- 
            property就是代表属性
              在spring中基本类型(包装类型和String)都可以用value来赋值
                                     引用类型用ref赋值
         -->
        <property name="pid" value="5"></property>
        <property name="pname" value="菜肉"></property>
        <property name="student">
            <ref bean="student"/>
        </property>
        <property name="lists">
            <list>
                <value>list1</value>
                <value>list2</value>
                <ref bean="student"/>
            </list>
        </property>
        <property name="sets">
            <set>
                <value>set1</value>
                <value>set2</value>
                <ref bean="student"/>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="map1">
                    <value>map1</value>
                </entry>
                <entry key="map2">
                    <value>map2</value>
                </entry>
                <entry key="map3">
                    <ref bean="student"/>
                </entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="prop1">
                    prop1
                </prop>
            </props>
        </property>
    </bean>
    <bean id="student" class="cn.itcast.spring0909.di.xml.set.Student"></bean>
</beans>

这里写图片描述

这里写图片描述

mvc

这里写图片描述

注解注入

步骤:
A. 在配置文件中,引入context命名空间

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring- beans-2.5.xsd
                      http://www.springframework.org/schema/context
                   http://www.springframework.org/schema/context/spring-context-2.5.xsd">

B. 在配置文件中加入context:annotation-config标签

这个配置隐式注册了多个对注释进行解析处理的处理器
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注: @Resource注解在spring安装目录的lib\j2ee\common-annotations.jar

这里写图片描述

@Autowired

这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
这里写图片描述

这里写图片描述

这里写图片描述
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。
这里写图片描述

@Qualifier

如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
这里写图片描述

这里写图片描述

这里写图片描述

@Resource

1、 @Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上.
2、 @Resource注解默认按名称装配。
名称可以通过@Resource的name属性指定,如果没有指定name属性,
• 当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象
• 当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
这里写图片描述

• 注意:如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

这里写图片描述

这里写图片描述

@PostConstruct 和 @PreDestroy

@PostConstruct :指定Bean的初始化方法
@PreDestroy : 指定Bean的销毁方法

这里写图片描述

这里写图片描述

扫描注入

前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

1、引入context命名空间 需要在xml配置文件中配置以下信息:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
          <context:component-scan base-package="cn.itcast"/>
</beans>

2、在配置文件中添加context:component-scan标签

     <context:component-scan base-package="cn.itcast"/>

这里写图片描述

其中base-package为需要扫描的包(含子包)。
注:

1、在使用组件扫描元素时,
AutowiredAnnotationBeanPostProcessor 和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。
2、功能介绍
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)、
@Repository用于标注数据访问组件,即DAO组件。
而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
这里写图片描述

这里写图片描述

这里写图片描述

spring中的继承

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

spring的IOC总结

spring的IOC:
  *  IOC:spring容器控制对象的生命周期:前提条件:在spring容器中的bean必须是单例的
       *  创建
          *  方式
             * 利用默认的构造函数,如果没有默认的构造函数,会报错
             * 利用静态工厂方法
             * 利用实例工厂方法
          *  时机
             *  lazy-init为“default/false”当启动spring容器的时候创建bean
                  但是如果该bean是prototype时,特殊。这种情况无效
                  *  在spring容器启动的时候,就会发现错误
                  *  有可能会造成一些数据长时间驻留在内存中
             *  lazy-init为"true"当context.getBean时创建
                  bean为多例时,必须用这种方案创建对象
                  *  不能及时发现错误
                  *  数据会在需要的时候加载
       *  初始化
            *  由spring容器调用init方法
            *  在构造函数之后执行
       *  销毁
            *  如果是单例,则必须返回ClassPathXmlApplicationContext该容器,才能执行销毁工作
            *  如果是多例,容器不负责销毁

spring容器关于ioc和di:启动过程

这里写图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐