zoukankan      html  css  js  c++  java
  • sping框架(3)— 使用spring容器

      spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。它们都可以代表spring容器,spring容器是生成bean实例的工厂,并管理容器中的bean。在spring中,所有的组件都被看做bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。

      应用中的所有组件都处于spring的管理下,都被spirng以bean的方式管理,spring负责创建bean实例,并管理生命周期。

    对于spring而言,一切java对象都是bean。

    spring容器

      spring容器最基本的接口就是BeanFactory,BeanFactory负责配置、创建、管理Bean,它有一个子接口:ApplicationContext,因此被称为spring的上下文。spring还负责管理bean和bean之间的依赖关系。

      BeanFactory接口包含如下几个方法:

      1.boolean containsBean(String name):判断spring容器是否包含id为name的bean实例;

      2.<T> T getBean(Class<T> requiredType):获取spring容器中属于requiredType类型的、唯一的bean实例;

      3.Object getBean(String name):返回容器中id为name的bean;

      4.<T> T getBean(String name, Class requiredType):返回容器中id为name,并且类型为requiredType的bean;

      5.Class<?>getType(String name):返回容器中id为name的bean的实例。

      

      调用者只需要使用getBean()方法即可获得指定bean的引用,无需关心bean的实例化过程,bean实例的创建、初始化以及依赖关系的注入都是由spring容器完成的。

      BeanFactory常用的实现类是DefaultListableBeanFactory。

      

      ApplicationContext是BeanFactory的子接口,对于大部分的java EE应用而言,使用它作为spring容器更加方便。其实现类是FileSystemXmlApplication、ClassPathXmlApplicationContext和AnnotationConfigApplicationContext。通常在web应用中,前两者的使用较多。

      创建spring的时候,必须提供spring容器管理的bean的详细信息,spring采用xml配置文件来声明配置信息。

       大多数Java EE应用,可在启动Web应用的时候自动加载ApplicationContext实例,接受spring管理的bean无需知道ApplicationContext的存在,一样可以使用ApplicationContext的管理。

      对于单独的应用程序,可以使用如下方式来创建BeanFactory。

    //搜索类加载路径下的beans.xml文件创建Resource对象
    Resource isr = new ClassPathResource("beans.xml");
    //创建默认的BeanFactory容器
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    //让默认的BeanFactory容器加载isr对应的XML配置文件
    new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(isr);
    

      也可以使用如下方式来创建BeanFactory

    //搜索类加载路径下的beans.xml文件创建Resource对象
    Resource isr = new FileSystemResource("beans.xml");
    //创建默认的BeanFactory容器
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    //让默认的BeanFactory容器加载isr对应的XML配置文件
    new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(isr);
    

      如果应用需要加载多个配置文件来创建spring容器,则应采用BeanFactory的子接口ApplicationContext来创建BeanFactory的实例。ApplcationContext接口包含了FileSystemXmlApplicationContextClassPathXmlApplicationContext连个常用的实现类。

       如果需要同时加载多个XML配置文件来创建spring容器,则可以采用ClassPathXmlApplicationContext如下方式:

    ApplicationContext  appContext = new 
    ClassPathXmlApplicationContext("beans.xml", "service.xml");
    

      也支持从文件系统的相对路径或绝对路径来搜索配置文件,使用FileSystemXmlApplicationContext方式:

    ApplicationContext  appContext = new 
    FileSystemXmlApplcationContext("beans.xml", "service.xml");
    

      

     ApplicationContext的事件机制

      ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理,如果容器中包含了一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent的时候,ApplicationListener Bean就会被触发。

      spring的事件框架有两个重要的成员。

      ApplicationEvent:容器事件,必须由ApplicationContext发布;

      ApplicationListener:监听器,可由容器中的任何监听器bean担任。

      spring的事件机制和其他事件机制基本相似,都需要由事件源、事件和事件监听器组成。只是此处的事件源是ApplicationContext,且事件必须由java程序显示触发。

    package org.crazyit.app.event;
    
    import org.springframework.context.ApplicationEvent;
    
    public class EmailEvent extends ApplicationEvent
    {
    	private String address;
    	private String text;
    	public EmailEvent(Object source)
    	{
    		super(source);
    	}
    	
    	public EmailEvent(Object source, String address, String text)
    	{
    		super(source);
    		this.address = address;
    		this.text = text;
    	}
    
    	public void setAddress(String address)
    	{
    		this.address = address;
    	}
    	
    	public String getAddress()
    	{
    		return this.address;
    	}
    	
    	public void setText(String text)
    	{
    		this.text = text;
    	}
    	
    	public String getText()
    	{
    		return this.text;
    	}
    }
    

      首先定义了一个ApplicationEvent类,对象是一个spring容器事件。(只要一个类继承了ApplicationEvent类,那么这个类就可作为spring容器的容器事件。)

      

    package org.crazyit.app.listener;
    
    import org.crazyit.app.event.EmailEvent;
    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.ApplicationListener;
    
    public class EmailNotifier implements ApplicationListener
    {
    	//只处理EmailEvent,模拟发送email通知
    	public void onApplicationEvent(ApplicationEvent evt)
    	{
    		//只处理EmailEvent,模拟发送email通知
    		if(evt instanceof EmailEvent)
    		{
    			EmailEvent emailEvent = (EmailEvent)evt;
    			System.out.print("需要发送邮件的接收地址: " + emailEvent.getAddress());
    			System.out.print("需要发送邮件的正文: " + emailEvent.getText());
    		}
    		else
    		{
    			//其他事件不做处理
    			System.out.print("其他事件: " + evt);
    		}
    	}
    
    }
    

      容器事件的监听器必须实现ApplicationListener接口,实现这个接口的时候,需要实现onApplicationEvent(ApplicationEvent evt)方法,每当容器中发生任何事件,这个方法就会被触发。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
    	xmlns = "http://www.springframework.org/schema/beans"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <bean class = "org.crazyit.app.Listener.EmailNotifier"/>
    </beans>
    

      将监听器配置在容器中,只需要在spring中配置一个实现了ApplicationListener接口的bean,spring就会将这个bean当做容器事件的监听器。

      当程序创建spring容器、加载spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件。除此之外,程序也可以调用ApplicationContext的publishEvent()方法来主动触发容器事件。比如下面的程序就是使用的这种方式。

    package lee;
    
    import org.crazyit.app.event.EmailEvent;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class SpringTest 
    {
    	public static void main(String[] args)
    	{
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    		EmailEvent ele = new EmailEvent("test", "spring@163.com", "this is a text");
    ctx.publishEvent(ele);
    	}
    }
    

      下划线的部分创建了ApplicationEvent对象,并通过ApplicationContext调用publicEvent()方法主动触发容器事件。

    其他事件: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@6ae40994: startup date [Fri Mar 31 14:23:49 CST 2017]; root of context hierarchy]
    需要发送邮件的接收地址: spring@163.com
    需要发送邮件的正文: this is a text
    

    让bean获取spring容器

      之前的例子中,程序先创建spring容器,然后调用spring容器的getBean()方法来获取spring容器中的bean。在这种访问模式下,程序总是持有spring容器的引用。

      但是在web应用中,spring容器通常采用声明式方式配置产生:开发者只需要在web.xml中配置一个Listener,该Listener负责初始化spring容器,前端MVC框架可以直接调用spring容器中的bean,无需访问spring容器本身,在这种情况下,容器中的bean处于容器管理下,无需主动访问容器,只需要接受容器的注入即可。

       在某些特殊情况下,bean需要实现某个功能,但该功能必须借助spring容器才能实现,此时就必须让该bean先获取spring容器,然后借助于spring容器来实现该功能。

      为了让bean获取它所在的spring容器,可以让bean实现BeanFactoryAware接口。

      在这个接口中只有一个方法setBeanFactory(BeanFactory beanFactory),这个方法中的参数代表创建它的BeanFactory。

      spring调用这个方法会将spring容器自身作为参数传入这个方法。

    spring容器中的bean

      spring容器就是超级大工厂, 

    能让一个男孩子热血的,不仅有梦想,还有姑娘。
  • 相关阅读:
    多库查询 sp_addlinkedserver使用方法(添加链接服务器)(转)片段整理
    利用asp.net路由实现url解析
    C#事务 访问数据库(转)
    男人30而立,30岁的男人喊起来!你们立了吗?
    c# 调用SQL Server存储过程返回值(转)
    转摘 JQUERY操作JSON例子
    jstree 从简单说起Jquery 插件应用说明
    利用反射对对象属性赋值取值操作
    asp.net 造成seesion 丢失的问题之一
    jquery 实现从左边listbox选择至右边listbox
  • 原文地址:https://www.cnblogs.com/Mr24/p/6612666.html
Copyright © 2011-2022 走看看