Spring IOC

什么是控制反转
什么是依赖注入
BeanFactory
ApplicationContext
Bean的scope
Bean的生命周期
Type2 Ioc、Type3 IoC
集合对象
资源、消息、事件


什么是控制反转?
IoC,用白话来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓的反转。

什么是依赖注入?
相对IoC 而言,“依赖注入”的确更加准确的描述了这种设计理念。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
依赖注入的几种实现类型
Type1 IoC(接口注入)
Type2 IoC(设值注入)
Type3 IoC(构造注入)

BeanFactory
BeanFactory负责读取Bean定义文件;管理对象的加载、生成;维护Bean对象与Bean对象之间的依赖关系;负责Bean的生命周期。BeanFactory接口包括了5种方法可以调用:
boolean containsBean(String name)
是否包含指定名称的Bean
Object getBean(String name)
取得相对应的Bean实例
Object getBean(String name,Class requiredType)
取得相对应的Bean实例,并转换到指定的类
Class getType(String name)
取得相对应的Bean的Class实例
boolean isSingleton(String name)
测试指定的Bean之scope是否为Singleton

ApplicationContext
ApplicationContext提供一个应用程序所需的更完整的框架功能,例如:
提供更方便地取得资源文件的方法
提供解析文字消息的方法
支持国际化消息
可以发布事件,对事件感兴趣的Bean可以接收这些事件

在实现ApplicationContext的类中,最常使用的是以下3个:
FileSystemXmlApplicationContext
可指定XML定义文件的相对路径或绝对路径读取定义文件
ClassPathXmlApplicationContext
从Classpath设置路径中读取XML定义文件
XmlWebApplicationContext
在Web应用程序的文件架构中,指定相对位置读取定义文件
举例:
可以将第一个Spring程序中的SpringDemo类修改为以下内容:
package org.fire;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemo {
    public static void main(String[] args) {
        ApplicationContext context=new
        ClassPathXmlApplicationContext("beans-config.xml");
        HelloBean hello=(HelloBean) context.getBean("helloBean");
        System.out.println(hello.getHelloWorld());
    }
}


Bean的scope
在Spring中,从BeanFactory或ApplicationContext取得的实例被默认为Singleton,也就是默认每一个Bean名称只维持一个实例。
使用Singleton模式产生单一实例,对单线程的程序来说不会有什么问题,但对于多线程的程序,必须注意到线程安全的问题,防止多个线程同时存取共用资源所引发的数据不同步问题,通常Singleton的Bean都是无状态的。
在Spring中,“scope”属性预设是“singleton”,通过将其设置为“prototype”,使得每次指定名称来取得Bean时,都会产生一个新的实例。
举例:
<bean id="date" class="java.util.Date" scope="singleton" />

Resource rs = new ClassPathResource("beans-config1.xml");
BeanFactory factory = new XmlBeanFactory(rs);
Date d1 = (Date) factory.getBean("date");
Thread.sleep(1000);
Date d2 = (Date) factory.getBean("date");
System.out.println(d1);
System.out.println(d2);

<bean id="date" class="java.util.Date" scope="prototype" />

Resource rs = new ClassPathResource("beans-config2.xml");
BeanFactory factory = new XmlBeanFactory(rs);
Date d1 = (Date) factory.getBean("date");
Thread.sleep(1000);
Date d2 = (Date) factory.getBean("date");
System.out.println(d1);
System.out.println(d2);

Bean的生命周期
一个Bean从建立到销毁,会历经几个执行阶段,我们可以在Bean的配置文件中定义“init-method”属性来设置初始化方法;定义“destroy-method”属性来设置销毁方法。
<bean id="beanLife“
    class="BeanLife"
    lazy-init="true"
    init-method="init"
    destroy-method="destroy">
</bean>

public class BeanLife {
  public void init(){
    System.out.println("init");
  }   
  public void destroy(){
    System.out.println("destroy");
  }   
  public static void main(String[] args) {   
    AbstractApplicationContext context=new       ClassPathXmlApplicationContext("applicationContext.xml");
    BeanLife life=(BeanLife) context.getBean("beanLife");
    //向JVM注册关闭
    context.registerShutdownHook();
  }
}


Type2 Ioc、Type3 IoC
在Spring中两种基本的依赖注入方式是设值注入及构造注入。在第1章完成的第一个Spring程序中,利用了Bean的Setter方法完成依赖注入。下面来介绍构造注入如何实现。
实现步骤:
JavaBean
import java.util.Date;

public class HelloBean {
    private String helloWorld;
    private Date date;
    public HelloBean(String helloWorld, Date date) {
        this.helloWorld = helloWorld;
        this.date = date;
    }
    ……
}

Bean的配置文件
<bean id="date" class="java.util.Date" />

<bean id="helloBean" class="HelloBean">
    <constructor-arg index="0">
        <value>Hello,fire</value>
    </constructor-arg>
    <constructor-arg index="1">
        <ref bean="date" />
    </constructor-arg>
</bean>

示范程序
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemo {
    public static void main(String[] args) {
         ApplicationContext context=new
         ClassPathXmlApplicationContext("applicationContext.xml");
         HelloBean hello=(HelloBean) context.getBean("helloBean");
         System.out.println(hello.getHelloWorld());
         System.out.println(hello.getDate());
    }
}


集合对象
对于Array、List 、Set 、Map等集合对象,在注入前必须填充入一些对象至集合中,然后再将集合注入至所需的Bean,也可以交由Spring的IoC容器来自动维护或生成集合对象,并完成依赖注入。
实现步骤:
JavaBean
import java.util.List;
import java.util.Map;

public class SomeBean {
    private String[] someArray;
    private List someList;
    private Map someMap;
    ……
}

Bean的配置文件
<bean id="someBean" class="SomeBean">
  <property name="someArray">
    <list>
      <value>1</value><value>2</value><value>3</value>
    </list>
  </property>
  <property name="someList">
    <list>
      <value>张三</value><value>李四</value><value>五王</value>
    </list>
  </property>
  <property name="someMap">
    <map>
      <entry key="1"><value>路人甲</value></entry>
      <entry key="2"><value>路人乙</value></entry>
    </map>
  </property>
</bean>

示范程序
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeBean some = (SomeBean) context.getBean("someBean");
// 取得Array类型依赖注入对象
String[] strs = some.getSomeArray();
for (int i = 0; i < strs.length; i++) {
    System.out.println(strs[i]);
}
// 取得List类型依赖注入对象
List list=some.getSomeList();
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
// 取得Map类型依赖注入对象
Map map=some.getSomeMap();
System.out.println(map.get("1"));
System.out.println(map.get("2"));


资源、消息、事件
资源的取得
ApplicationContext.getResource()方法提供了对资源文件访问的支持,示例如下:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//获得资源对象
Resource rs = context.getResource("classpath:test.txt");
// Resource rs = context.getResource("file:src/test.txt");
//资源文件是否存在
if (rs.exists()) {
    //输出资源文件的绝对路径
    System.out.println(rs.getFile().getAbsolutePath());
    //获得资源文件的输入流对象
    InputStream in=rs.getInputStream();
    InputStreamReader inr=new InputStreamReader(in);
    while(inr.ready()){
        System.out.print((char)inr.read());
    }
    in.close();inr.close();
}

解析文字消息
ApplicationContext继承了MessageSource接口,可以使用getMessage()的各种版本的方法来取得文字消息的资源文件,从而实现国际化消息的目的。
messages_en.properties
User {0} login at {1}
messages_zh.properties
用户 {0} 于 {1} 登录

<!-- 使用ResourceBundleMessageSource来取国际化消息 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
  <!-- 设置消息资源的前置档案文件名称 -->
  <property name="basename" value="messages"></property>
</bean>

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 消息中需要传递的参数
Object[] arg = { "Fire", new Date() };
// 输出英文消息
System.out.println(context.getMessage("userLogin", arg, Locale.US));
// 输出中文消息
System.out.println(context.getMessage("userLogin", arg, Locale.CHINA));

事件传播
如果打算发布事件通知ApplicationListener的实例,可以使用ApplicationContext的publishEvent()方法。示例如下:
//自定义动作事件
public class ActionEvent extends ApplicationEvent {
    public ActionEvent(Object source) {
        super(source);
    }
}

<bean id="listener" class="ActionListener" />

//自定义动作事件监听器
public class ActionListener implements ApplicationListener{
    public void onApplicationEvent(ApplicationEvent event) {
        if(event instanceof ActionEvent){
            System.out.println(event.getSource());
        }
    }
}

ApplicationContext context = new     ClassPathXmlApplicationContext("applicationContext.xml");
context.publishEvent(new ActionEvent("Hello"));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值