Spring笔记――2.使用Spring容器
2015-09-01 10:38
344 查看
Spring有两个核心接口:BeanFactory和ApplicationContext。而ApplicationContext是BeanFactory的子接口,都可以代表Spring容器,用于产生管理Bean们。我们经常使用ApplicationContext以及它的实现类ClassPathXmlApplicationContext。当创建ApplicationContext时,会实例化所有的单例Bean,花销较大,但之后性能较好。如果为bean设置lazy-init为true,则不会在开始初始化。
国际化支持ApplicationContext集成了MessageSource接口,具有国际化功能。当程序创建ApplicationContext容器时,架构会去找messageSource这个Bean,然后接口中的getMessage(String code,Object[] args, Locale loc)与getMessage(String code, Object[] args, String default, Local loc)就会被交给messageSource这个bean使用。如果没找到,则会穿件一个StaticMessageSource,由它调用两个方法。其中第二个参数的对象组是为了填补国际化文件中的{0}、{1}这些的。这个bean的id规定死了必须是messageSource,而实现类也规定死了必须这么写。
让Bean获取Spring容器之前的例子中我们都是先new一个ApplicationContext实例,然后通过实例操作。这种情况下,程序中总是持有Spring容器的引用。Web应用中,Spring容器通常采用声明方式配置产生。开发者需要在web.xml中设一个listener,它会负责初始化容器,前段mvc框架可以直接调用bean,无需通过容器。但是有的时候,bean需要实现某个功能比如国际化(这个bean中需要使用ctx,使用的是容器实例的getMessage方法),而他们必须借助容器才能完成,因此还是要先得到容器,再实现功能。为了能让某一个bean得到他的爸爸:容器,可以让这个bean实现BeanFactoryAware接口,它里面有一个gesetBeanFactory方法,它的参数就是指向创建它的容器。这个set方法是由Spring调用的。
国际化支持ApplicationContext集成了MessageSource接口,具有国际化功能。当程序创建ApplicationContext容器时,架构会去找messageSource这个Bean,然后接口中的getMessage(String code,Object[] args, Locale loc)与getMessage(String code, Object[] args, String default, Local loc)就会被交给messageSource这个bean使用。如果没找到,则会穿件一个StaticMessageSource,由它调用两个方法。其中第二个参数的对象组是为了填补国际化文件中的{0}、{1}这些的。这个bean的id规定死了必须是messageSource,而实现类也规定死了必须这么写。
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>包名/资源文件组1</value> <value>包名1/包名2/资源文件组2</value> </list> </property> </bean>由于容器已经集成了MessageResource这个接口,因此容器实例能够直接调用getMessage这个方法。
String hello=act.getMessage("hello", new String[] {"A"}, Locale.getDefault());ApplicationContext的事件机制通过ApplicationEvent抽象类(必须由ApplicationContext发布)和ApplicationListener(容器中任意的bean承担)接口可以实现ApplicationContext的事件处理。如果容器中有一个bean实现了ApplicationListener这个接口,每当ApplicaitonContext发布ApplicationEvent,ApplicationLIstener Bean将会自动被触发。我们都知道事件机制需要事件源,事件和监听器。事件源此处是ApplicationContext,必须由java程序显式触发。事件如下,必须继承ApplicationEvent父类
package com.cm.event; import org.springframework.context.ApplicationEvent; public class EmailEvent extends ApplicationEvent { private String address; private String text; 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; } public EmailEvent(Object source,String address,String text) { super(source); this.address=address; this.text=text; // TODO Auto-generated constructor stub } public EmailEvent(Object source) { super(source); // TODO Auto-generated constructor stub } }上述代码中提供了两个不同的构造函数。构造函数需要被传入一个bean实例。监听器如下,需要实现ApplicationListener接口:
public class EmailNotifier implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent arg0) { // TODO Auto-generated method stub if(arg0 instanceof EmailEvent){ EmailEvent emailEvent=(EmailEvent)arg0; System.out.println("需要发送邮件的接收地址"+emailEvent.getAddress()); System.out.println("需要发送邮件的征文"+emailEvent.getText()); }else{ System.out.println("other!!!!!!!!!!!"+arg0); }} }上述代码中的方法就是对接口的实现。这个方法的形参就是容器发布的事件的类型。由于所有实现了接口的监听器都会在事件发布时被启动,因此我们需要这个参数来判断到底是哪个实例出发的事件。我们会得到的 注意我们在xml中配置的只有监听器,而事件是显式触发的(当然有些时候也需要配置,不过本例中我们还是使用了new,因为没有用到依赖关系)
<bean class="com.cm.event.EmailNotifier">显式触发事件
ApplicationContext act=new ClassPathXmlApplicationContext("beans.xml"); EmailEvent ele=new EmailEvent("test","1357@qq.com","my email"); act.publishEvent(ele);总结如下:当程序发布了一个事件(内置事件不需要手动发布,会自动监听),xml中的所有监听器就会自动被启动,并执行相应程序。
让Bean获取Spring容器之前的例子中我们都是先new一个ApplicationContext实例,然后通过实例操作。这种情况下,程序中总是持有Spring容器的引用。Web应用中,Spring容器通常采用声明方式配置产生。开发者需要在web.xml中设一个listener,它会负责初始化容器,前段mvc框架可以直接调用bean,无需通过容器。但是有的时候,bean需要实现某个功能比如国际化(这个bean中需要使用ctx,使用的是容器实例的getMessage方法),而他们必须借助容器才能完成,因此还是要先得到容器,再实现功能。为了能让某一个bean得到他的爸爸:容器,可以让这个bean实现BeanFactoryAware接口,它里面有一个gesetBeanFactory方法,它的参数就是指向创建它的容器。这个set方法是由Spring调用的。
public class Aperson implements ApplicationContextAware { private ApplicationContext ctx; @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { // TODO Auto-generated method stub this.ctx=arg0; } public void sayHi(String name){ System.out.println(ctx.getMessage(arg0, arg1)); } }架构会扫面所有的bean看哪个有接口ApplicationContextAware,然后使用set方法传入容器实例。此bean的测试程序省略。。。测试中调用了sayHi方法,而这个方法自己没法完成功能,需要ctx的getMessage,因此它得想法得到容器实例。那就实现一个接口吧,Srping会为这个接口的set方法传入一个容器实例,将传入值赋给自己的成员变量吧!本文出自 “指尖轻飞” 博客,谢绝转载!
相关文章推荐
- Spring 3 MVC深入研究
- java调用免费天气接口
- 说说最近一段时间找工作的事(Java后端开发)
- Spring-IOC简单原理 + 实现
- 【备忘】java swing 焦点控制全纪录
- java 匿名内部类 抽象类跟接口可以直接New出来啊~~
- Java 内存泄露以及几种不同的引用
- 问题解决——Ubuntu中eclipse不显示目录
- Java实现链式存储的线性表
- struts初探
- MyEclipse8.5 jad 反编译工具 插件安装
- java Web项目启动 执行一个方法,执行一个清理工作
- Java多线程中Sleep与Wait的区别
- 基于数组实现顺序存储的线性表
- MyBatis Spring 注解事务配置
- Java多线程之 Thread VS Runnable
- JAVA BST的实现
- Eclipse中查看JDK源码设置
- 深入理解java虚拟机【并发编程缓存】
- maven与springMVC之类型转换器