Spring学习笔记-Spring容器
2015-09-08 08:31
483 查看
Spring容器顾名思义是用来容纳(装)东西的,装的就是Bean。Spring容器负责创建、配置、管理Bean。Spring容器有两个核心接口:BeanFactory和ApplicationContext接口,后者是前者的子接口。在基于Spring的Java EE程序中,所有的组件都被当成Bean来处理,包括数据源对象、Hibernatede的SessionFactory、事务管理等,程序中的所有java类都可以被当做Spring容器中的Bean。
1. Spring容器
Spring容器的核心接口就是BeanFactory,它有一个子接口就是ApplicationContext。ApplicationContext也被称为Spring上下文。
调用者只需要使用getBean()方法(此方法有多个重载可以通过不同形式来获取Bean)即可获得指定Bean的引用。对于大部分的Java EE程序而言,使用ApplicationContext作为Spring容器更方便。其常用的实现类有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotationConfigXmlApplicationContext。如果在Java Web中使用Spring容器,则通常有XmlWebApplicationContext、AnnotationConfigWebApplicationContext两个容器。
创建Spring容器的实例时,必须提供Spring容器管理的Bean的配置文件,也就是我们常说的Spring Xml配置文件。因此在创建BeanFactory时配置文件作为参数传入。Xml配置文件一般以Resource对象传入。Resource是Spring提供的资源访问接口,通过该接口Spring能简单、透明的访问磁盘、网络系统和类路径上的相关资源。
对于独立的Java EE应用程序,可以通过如下方法来实例化BeanFactory。
在Web中可以利用如ContextLoader的支持类,在Web应用启动的时候自动创建ApplicationContext。
除了提供BeanFactory所支持的全部功能外,Application还额外的提供了如下功能:
ApplicationContext会默认初始化所有的singleton Bean(单例Bean),也可以通过配置取消。
ApplicationContext继承了MessageSource接口,因此提供国际化支持。
资源访问,比如URL和文件。
事件机制。
同时加载多个配置文件。
以声明式方式启动并创建Spring容器。
ApplicationContext包括了BeanFactory的所有功能,并提供了一些额外的供,一次建议优先使用ApplicationContext。对于某些内存在意内存消耗的,才考虑使用BeanFactory。
当系统创建ApplicationContext容器时,会默认初始化singleton Bean,包括调用构造器创建该Bean的实例,通过元素驱动Spring调用setter方法注入所依赖的对象。这就意味着,系统前期创建ApplicationContext会有很大的开销,但是一旦初始化完成后面的获取Bean实例就会拥有较好性能。为了阻止在使用ApplicationContext作为Spring容器初始化singleton Bean可以在元素添加 lazy-init=”true”属性。
Spring国际化的支持,其实是建立在Java国际化的基础上的。其核心思路将程序中需要国际化的信息写入资源文件,而代码中仅仅使用国际化信息相应的Key。
Spring事件框架有两个核心的接口:
ApplicationEvent(事件):必须由ApplicationContext来发布。
ApplicationListener(监听器):实现了此接口就可以担任容器中的监听器Bean。
实际上,Spring的事件机制和所有的事件机制都基本相似。都是由事件(实现ApplicationEvent接口的类)、事件源(也就是Spring容器,并且有java代码显示的触发)、监听器(ApplicationListener接口实现类)。这就像我们在页面点击了一个button。button就是事件源,单击的这个动作就是事件,处理函数就是监听器。
一下代码演示了Spring事件机制。
Spring配置文件:
我们从上面的代码可以看出,事件监听器不仅监听到了我们程序显示触发的事件,还监听到了Spring容器内置的事件。如果实际开发需要,我们可以在Spring容器初始化或销毁时回调自定义方法,就可以通过上面的事件监听机制来完成。
Spring提供了如下几个内置事件:ContextRefreshedEvent、ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent、RequestHandledEvent。
在某些特殊情况下,Bean需要实现某个功能(比如:Bean需要输出国际化信息,或向Spring容器发布事件),这些功能都需要借助Spring容器来完成。也就说我们需要将Spring容器也作为一个Bean来注入到其他Bean中,只不过Spring容器Bean是一个容器级别的Bean。
为了让Bean取得它所在容器的引用,可以让Bean实现BeanFactoryAware接口。该接口只有一个方法setBeanFactory(BeanFactory beanFactory)方法,方法的beanFactory参数指向Spring容器,会由Spring容器注入。看到这来我们会感觉奇怪,我们在Bean中定义一个setter方法后,通常都是由在配置文件中配置元素来驱动Spring容器来注入依赖Bean的,但是这里我们并没有这样做。这是因为一个Bean如果实现了BeanFactory接口,Spring在创建该Bean时,会自动注入Spring容器本身。与BeanFactoryAware接口类似的还有BeanNameAware、ResourceLoaderAware接口,这些接口都会提供类似的setter方法,这些方法都会由Spring容器来注入。
下面我们来演示一个示例,这个示例中的Person类中的sayHi()方法将输出国际化消息,这就需要Person获取Spring容器,借助Spring容器来完成国际化。
message_zh_CN.properties国际化资源文件
message_en_US.properties国际化资源文件
1. Spring容器
Spring容器的核心接口就是BeanFactory,它有一个子接口就是ApplicationContext。ApplicationContext也被称为Spring上下文。
调用者只需要使用getBean()方法(此方法有多个重载可以通过不同形式来获取Bean)即可获得指定Bean的引用。对于大部分的Java EE程序而言,使用ApplicationContext作为Spring容器更方便。其常用的实现类有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotationConfigXmlApplicationContext。如果在Java Web中使用Spring容器,则通常有XmlWebApplicationContext、AnnotationConfigWebApplicationContext两个容器。
创建Spring容器的实例时,必须提供Spring容器管理的Bean的配置文件,也就是我们常说的Spring Xml配置文件。因此在创建BeanFactory时配置文件作为参数传入。Xml配置文件一般以Resource对象传入。Resource是Spring提供的资源访问接口,通过该接口Spring能简单、透明的访问磁盘、网络系统和类路径上的相关资源。
对于独立的Java EE应用程序,可以通过如下方法来实例化BeanFactory。
//在当前项目类路径下搜索配置文件 ApplicationContext appContext = new ClassPathXmlApplicationContext("beans_7_3_3.xml"); //在文件系统搜索配置文件 appContext = new FileSystemXmlApplicationContext("D:\\spring-tool-workspace\\myspring\\src\\beans_7_3_3.xml"); //获取chinese的Bean,并且返回的类型为Chinese Person chinese = appContext.getBean("chinese", Chinese.class); chinese.useAxe();
2.使用ApplicationContext
大部分时候,都不会使用BeanFactory实例作为Spring容器,而是使用ApplicationContext作为Spring容器,因此Spring容器也被称为Spring上下文。ApplicationContext增强了BeanFactory的功能,提供了很多有用、方便开发的功能。在Web中可以利用如ContextLoader的支持类,在Web应用启动的时候自动创建ApplicationContext。
除了提供BeanFactory所支持的全部功能外,Application还额外的提供了如下功能:
ApplicationContext会默认初始化所有的singleton Bean(单例Bean),也可以通过配置取消。
ApplicationContext继承了MessageSource接口,因此提供国际化支持。
资源访问,比如URL和文件。
事件机制。
同时加载多个配置文件。
以声明式方式启动并创建Spring容器。
ApplicationContext包括了BeanFactory的所有功能,并提供了一些额外的供,一次建议优先使用ApplicationContext。对于某些内存在意内存消耗的,才考虑使用BeanFactory。
当系统创建ApplicationContext容器时,会默认初始化singleton Bean,包括调用构造器创建该Bean的实例,通过元素驱动Spring调用setter方法注入所依赖的对象。这就意味着,系统前期创建ApplicationContext会有很大的开销,但是一旦初始化完成后面的获取Bean实例就会拥有较好性能。为了阻止在使用ApplicationContext作为Spring容器初始化singleton Bean可以在元素添加 lazy-init=”true”属性。
3.ApplicationContext的国际化支持
ApplicationContext接口继承了MessageSource接口,因此具备国际化功能。String getMessage(String code, Object [] args, Locale loc)和String getMessage(String code, Object[]args, String default, Locale loc)方法是MessageSource接口提供的国际化的两个方法。Spring国际化的支持,其实是建立在Java国际化的基础上的。其核心思路将程序中需要国际化的信息写入资源文件,而代码中仅仅使用国际化信息相应的Key。
4.ApplicationContext的事件机制
ApplicationContext的事件机制是观察者设计模式的实现。通过ApplicationEvent和ApplicationListeren接口实现,前者是被观察者,后者是观察者。Spring事件框架有两个核心的接口:
ApplicationEvent(事件):必须由ApplicationContext来发布。
ApplicationListener(监听器):实现了此接口就可以担任容器中的监听器Bean。
实际上,Spring的事件机制和所有的事件机制都基本相似。都是由事件(实现ApplicationEvent接口的类)、事件源(也就是Spring容器,并且有java代码显示的触发)、监听器(ApplicationListener接口实现类)。这就像我们在页面点击了一个button。button就是事件源,单击的这个动作就是事件,处理函数就是监听器。
一下代码演示了Spring事件机制。
/** * 定义一个Spring ApplicationContext类 * @author hsoft3 * */ 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 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; } }
/** * 定义一个 Spring ApplicationListener类 * @author hsoft3 * */ public class EmailNotifier implements ApplicationListener<ApplicationEvent> { @Override public void onApplicationEvent(ApplicationEvent event) { //处理EmailEvent事件 if(event instanceof EmailEvent){ EmailEvent email = (EmailEvent)event; System.out.print(email.getAddress()+" "+email.getText()); }else{ //输出Spring容器的内置事件 System.out.println("其它事件:"+event); } } public static void main(String [] args){ ApplicationContext appContext = new ClassPathXmlApplicationContext("beans_7_4_4.xml"); //EmailEvent emailEvent = new EmailEvent("test", "创新路", "工大"); EmailEvent emailEvent = appContext.getBean("emailEvent", EmailEvent.class); appContext.publishEvent(emailEvent); } }
Spring配置文件:
<bean class="com.ssh.zxy.chapter7_4_4.EmailNotifier"></bean> <bean id="emailEvent" class="com.ssh.zxy.chapter7_4_4.EmailEvent"> <constructor-arg value="test"></constructor-arg> <constructor-arg value="123@qq.com"></constructor-arg> <constructor-arg value="this is a test"></constructor-arg> </bean>
我们从上面的代码可以看出,事件监听器不仅监听到了我们程序显示触发的事件,还监听到了Spring容器内置的事件。如果实际开发需要,我们可以在Spring容器初始化或销毁时回调自定义方法,就可以通过上面的事件监听机制来完成。
Spring提供了如下几个内置事件:ContextRefreshedEvent、ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent、RequestHandledEvent。
5.让Bean获取Spring 容器
我们上几个事例都是程序通过ApplicationContext创建Spring容器,在调用Spring容器的getBean()方法,来获得Bean。这种情况下,程序总是持有Spring容器的引用。但是在Web应用中,我们可以用声明式的方法来创建Spring容器:在web.xml文件中配置一个监听,让这个监听类帮我们来创建Spring容器,前端MVC框架直接调用bean,使用依赖注入功能,无需访问Spring容器本身。在某些特殊情况下,Bean需要实现某个功能(比如:Bean需要输出国际化信息,或向Spring容器发布事件),这些功能都需要借助Spring容器来完成。也就说我们需要将Spring容器也作为一个Bean来注入到其他Bean中,只不过Spring容器Bean是一个容器级别的Bean。
为了让Bean取得它所在容器的引用,可以让Bean实现BeanFactoryAware接口。该接口只有一个方法setBeanFactory(BeanFactory beanFactory)方法,方法的beanFactory参数指向Spring容器,会由Spring容器注入。看到这来我们会感觉奇怪,我们在Bean中定义一个setter方法后,通常都是由在配置文件中配置元素来驱动Spring容器来注入依赖Bean的,但是这里我们并没有这样做。这是因为一个Bean如果实现了BeanFactory接口,Spring在创建该Bean时,会自动注入Spring容器本身。与BeanFactoryAware接口类似的还有BeanNameAware、ResourceLoaderAware接口,这些接口都会提供类似的setter方法,这些方法都会由Spring容器来注入。
下面我们来演示一个示例,这个示例中的Person类中的sayHi()方法将输出国际化消息,这就需要Person获取Spring容器,借助Spring容器来完成国际化。
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>com/ssh/zxy/chapter7_4_5/messages/message</value> </list> </property> </bean> <bean id="person" class="com.ssh.zxy.chapter7_4_5.Person"></bean>
//这里实现了ApplicationContextAware接口原理同BeanFactoryAware接口 public class Person implements ApplicationContextAware { private ApplicationContext appContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.appContext= applicationContext; } public void sayHi(String name){ Locale locale = Locale.getDefault(Locale.Category.FORMAT); String myName = appContext.getMessage("name", new String[]{name}, locale); System.out.println(myName); myName = appContext.getMessage("name", new String[]{name}, Locale.US); System.out.println(myName); } public static void main(String [] args){ System.out.print(Person.class.getClassLoader().getResource(".").getPath()); ApplicationContext appContextMain = new ClassPathXmlApplicationContext("beans_7_4_5.xml"); Person p = appContextMain.getBean("person", Person.class); p.sayHi("小明"); } }
message_zh_CN.properties国际化资源文件
name=CH \u4F60\u597D,{0}
message_en_US.properties国际化资源文件
name=US hi,{0}
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- java实现简单美女拼图游戏
- java基本教程之线程休眠 java多线程教程
- JSP开发中在spring mvc项目中实现登录账号单浏览器登录
- 基于Spring框架的Shiro配置方法
- Spring MVC中上传文件实例
- 实例讲解Java的Spring框架中的AOP实现
- 解析Java中如何获取Spring中配置的bean
- Spring的注解配置与XML配置之间的比较
- java Spring整合Freemarker的详细步骤
- Java 二维码,QR码,J4L-QRCode 的资料整理
- java当中的定时器的4种使用方式
- java中 spring 定时任务 实现代码