Spring应用(一) IOC和DI总结

一、IOC和DI的概念描述

1.1概念

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。


1.2技术描述

Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。
采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。


1.3实现方法

实现控制反转主要有两种方式:依赖注入和依赖查找。两者的区别在于,前者是被动的接收对象,在类A的实例创建过程中即创建了依赖的B对象,通过类型或名称来判断将不同的对象注入到不同的属性中,而后者是主动索取响应名称的对象,获得依赖对象的时间也可以在代码中自由控制。


二、Spring IOC详解

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

2.1步骤

A.启动spring容器
1、在类路径下寻找配置文件来实例化容器
    ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});可以在整个类路径中寻找xml文件
              * 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
              *  classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。 
2、在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。

注:经常用第一种方法启动容器

B.从spring容器中提取对象

2.2 配置文件中的属性

2.2.1 别名(alias)
<beans> 
    <bean name="person" class="cn.alias.spring.Person"/>
    <alias name="person" alias="p"/>
</beans>

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

2.2.2 bean对象的scope
singleton(默认值)

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

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

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

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

这里写图片描述

prototype

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

2.2.3 Lazy-init

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

2.2.4init、destroy

Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。

<bean id=“foo” class=“...Foo” init-method=“setupdestory-method=“teardown”/>

当foo被载入到Spring容器中时调用init-method方法。当foo从容器中删除时调用destory-method(scope = singleton有效)


2.3 创建对象的三种方式

2.3.1 无参构造函数
<bean id=“personService" class="cn.bean.impl.PersonServiceImpl"/>

* 要求PersonServiceImpl有无参构造方法
* spring容器在默认的情况下使用默认的构造函数创建对象

2.3.2 静态工厂方法
<bean id="personService" class="com.factory.PersonServiceFactory" factory-method="createPersonService" />


public class PersonServiceFactory {
      public  static PersonService createPersonService(){
                return new PersonServiceImpl();
      }
}
/**
 * 在spring容器 内部,调用了PersonServiceFactory中的createPersonService方法
 * 而该方法的内容就是创建对象的过程,是由程序员来完成
 */
2.3.3 实例工厂
<bean id="helloWorldFactory" class="com.spring.ioc.createobject.method.HelloWorldFactory2"></bean>

    <!-- 
        factory-bean指向了实力工厂的bean
        factory-method实例工厂对象的方法
     -->
<bean id="helloWorld" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>
/**
 * 实例工厂
 *   1、spring容器创建一个实例工厂bean
 *   2、该bean调用了工厂方法getInstance产生对象
 */

三、Spring DI详解

依赖注入(Dependence Injection)是把Spring创建的对象注入到Java类中

有三种注入方式,分别为setter注入,构造器注入,注解注入,其中前两种方法都是在xml文件中配置

3.1 setter注入

    <bean id="person" class="com.spring.di.xml.setter.Person">
        <!-- 
            property描述的就是bean中的属性
              name属性就是描述属性的名称
              value就是值   如果是基本属性(String),就用value赋值
              ref  如果是引用类型,用ref赋值
         -->
        <property name="pid" value="1"></property>
        <property name="name" value="王二麻子"></property>
        <property name="student" ref="student"></property>
        <property name="lists">
            <list>
                <value>list1</value>
                <value>list2</value>
                <!-- 
                    list中存放一个student对象
                 -->
                <ref bean="student"/>
            </list>
        </property>
        <property name="objects">
            <list>
                <value>obj1</value>
                <ref bean="student"/>
            </list>
        </property>
        <property name="sets">
            <set>
                <value>set1</value>
                <ref bean="student"/>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="m1">
                    <value>m1</value>
                </entry>
                <entry key="m2">
                    <ref bean="student"/>
                </entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="p1">p1</prop>
                <prop key="p2">p2</prop>
            </props>
        </property>
    </bean>

3.2 构造器注入

    <bean id="person" class="com.spring.di.xml.constructor.Person">
        <!-- 
            constructor-arg  代表某一个构造器的参数
              index 构造器参数的下标
              value
              ref
              type  类型
         -->
        <constructor-arg index="0" value="1" type="java.lang.String"></constructor-arg>
        <constructor-arg index="1" ref="student"></constructor-arg>
    </bean>

Person类中:

    public Person(String name,Student student){
        this.name  = name;
        this.student = student;
    }

3.3 注解注入

3.3.1 步骤

步骤:
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标签

<context:annotation-config/> 

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

3.3.2 @Resource

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


/**
 * 1、启动spring容器
 * 2、把spring配置文件中的bean实例化(person,student)
 * 3、当spring容器解析配置文件
 *     <context:annotation-config></context:annotation-config>
 *    spring容器会在纳入spring管理的bean的范围内查找哪些类的属性上是否加有@Resource注解
 * 4、如果在属性上找到@Resource注解
 *      如果@Resource的注解的name属性的值为""
 *           则把@Resource所在的属性的名称和spring容器中的id作匹配
 *                  如果匹配成功,则赋值
 *                  如果匹配不成功,则会按照类型进行匹配
 *                      如果匹配成功,则赋值,匹配不成功,报错
 *      如果@Resource的注解的name属性的值不为""
 *           则解析@Resource注解name属性的值,把值和spring容器中的ID进行匹配
 *               如果匹配成功,则赋值
 *               如果匹配不成功,则报错
 *               
 * 说明:
 *     注解代码越来越简单,效率越来越低
 *     注解只能应用于引用类型
 */

@Autowired和@Qualifier结合起来用与@Resource效果一样

3.3.3 @Autowired

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

3.3.4 @Qualifier
3.3.4 @PostConstruct

指定Bean的初始化方法

3.3.4 @PreDestroy

指定Bean的销毁方法

3.4 Spring中的继承

Spring-Context之九:在bean定义中使用继承
作者:黄博文@无敌北瓜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值