二、Spring容器使用
1.Spring容器
(1)Spring容器最基本的接口就是BeanFactory接口。BeanFactory负责配置、创建、管理Bean,同时也管理Bean与Bean之间的依赖关系;
(2)BeanFactory包含的方法:
import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;public class Test2 { public static void main(String[] args) { //搜索类加载路径下的配置文件 Resource isr = new ClassPathResource("test2.xml"); //创建BeanFactory容器 //DefaultListableBeanFactoru是BeanFactory的实现类 DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); //让默认的BeanFactory容器加载isr对应的xml文件 new XmlBeanDefinitionReader(bf).loadBeanDefinitions(isr); //判断容器是否包含id为chinese的Bean实例 System.out.println(bf.containsBean("chinese")); //获取容器中类型为Chinese的唯一的Bean实例 Chinese a = bf.getBean(Chinese.class); //返回容器id为name的bean实例,需要类型转换 Chinese b = (Chinese) bf.getBean("chinese"); //返回容器中id为name的bean实例,不需要类型转换 Chinese c = bf.getBean("chinese",Chinese.class); //获取容器中id为name的bean实例的类型 Class clazz = bf.getType("chinese"); }}
(3)同时加载多个配置文件时,使用BeanFactory的子接口ApplicationContext接口
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test3 { public static void main(String[] args) { //创建Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("text1.xml","text2.xml"); }}
2.ApplicationContext
(1)ApplicationContext是BeanFactory的子接口,ApplicationContext增强了BeanFactory的功能,通常情况下,使用ApplicationContext实例作为容器使用;
(2)ApplicationContext除了有所有BeanFactory的功能外,同时添加了如下的额外功能:
1)默认预初始化所有的singleton Bean,也可取消预初始化;
2)提供国际化支持;
3)资源访问,如访问URL和文件;
4)事件机制;
5)同时加载多个配置文件;
6)以声明的方式启动并创建Spring容器;
3.ApplicationContext的事件机制
(1)通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动触发;
(2)Spring的事件框架有两个重要成员:
1)ApplicationEvent:容器事件,必须由AppicationContext发布;
2)ApplicationListener:监听器,可由容器中的任何监听器Bean担任;
(3)Spring容器事件机制:
(4)示例:
事件:
import org.springframework.context.ApplicationEvent;//只要一个类继承了ApplicationEvent类,就可以当做一个容器事件public class EmailEvent extends ApplicationEvent{ private String address; private String text; public EmailEvent(Object source) { super(source); //调用父类构造器 // TODO Auto-generated constructor stub } //初始化全部成员变量的构造器 public EmailEvent(Object source,String address,String text){ super(source); //调用父类构造器 this.address = address; this.text = text; } //setter、getter方法 public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getText() { return text; } public void setText(String text) { this.text = text; }}
监听器:
import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;//容器事件的监听器必须实现ApplicationListener接口public class EmailNotifier implements ApplicationListener{ //实现ApplicationListener接口必须实现该方法 //该方法将会在容器事件发生时自动触发 @Override public void onApplicationEvent(ApplicationEvent evt) { // TODO Auto-generated method stub if(evt instanceof EmailEvent){ EmailEvent emailEvent = (EmailEvent)evt; System.out.println("需要发送邮件的接收地址:"+emailEvent.getAddress()); System.out.println("需要发送邮件的正文:"+emailEvent.getText()); }else{ //其他事件不做任何处理 System.out.println("其他事件:"+evt); } } }
配置文件:
主程序:
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test { public static void main(String[] args) { //创建Spring容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("test3.xml"); //创建一个ApplicationEvent对象 EmailEvent emailEvent = new EmailEvent("test", "address:地址", "text:内容"); //发布容器事件 ctx.publishEvent(emailEvent); }}
4.让Bean获取Spring容器
(1)在web应用中,Spring容器通常采用声明式方式配置产生:开发者只要在web.xml文件中配置一个Listener,该Listener会负责初始化Spring容器,前端MVC框架可以直接调用Spring容器中的Bean,无须访问容器本身。在这种情况下,容器中的Bean处于容器管理下,无须主动访问容器,只要接受容器的依赖注入即可;
(2)如下情况,某个Bean需要向容器发布事件,但该功能必须通过Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助Spring容器来实现该功能;为了让Bean能够获取它所在的容器,其Bean必须实现接口ApplicationContextAware,
实现该接口必须实现setApplicationContext(ApplicationContext applicationContext)方法,该方法由Spring调用,传入的参数为容器本身。通过这个方法,可以让Bean获取到所在容器。
(3)示例:
容器事件为上文中的EmailEvent,时间监听器为上文中的EmailNotifier
Person类:
import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import test3.EmailEvent;//该person需要实现发布容器事件的功能//发布容器事件必须通过容器//使这个Person类实现ApplicationContextAware接口public class Person implements ApplicationContextAware{ //用成员变量的形式保存容器 private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } public void pEvent(){ EmailEvent emailEvent = new EmailEvent("test","address:地址","text:内容"); applicationContext.publishEvent(emailEvent); }}
配置文件:
主程序:
import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("test3.xml"); Person p = ctx.getBean("person",Person.class); p.pEvent(); }}