spring的BeanFactory 和ApplicationContext详解

BeanFactory和ApplicationContext 是使用过Spring的同学耳熟能详的两个接口,其中BeanFactory是Spring框架最核心的接口,之前学习Spring开发的时候接触多的是ApplicationContext 这个面向应用的功能,当然要搭建Spring环境也可以不用了解BeanFactory这个接口,简而言之:

BeanFactor:y提供了高级的IoC的配置机制,管理不同类型的Java对象,是Spring框架的基础设施,面向的是Spring本身。

ApplicationContext:是建立在BeanFactory基础之上的,它提供了更多的面向应用的功能,诸如国际化支持,框架事件体系,易于创建实际应用,面向使用Spring的开发者。

这里先说说Spring里面的Resource接口:

Resource:为应用提供了强大的访问底层资源,下面UML列出了它的主要接口和鸡翅根体系:

这三个是常用的,这三个子类可以见名知意了,还有如:

InputStreamResource:对应的是InputStream的资源。

ServletContxtResource:负责Web应用根目录的路径加载资源,支持URL的方式访问,可以直接从jar包中访问资源。

UrlResource:可以访问任何可以通过URL表示的资源,如HTTP资源,FTP资源。

FileSystemResource:

01. public class FileSourceDemo {
02.  
03. public static void main(String[] args) {
04.  
05. String filePath ="E:\\Workspace_64bit\\Myeclipses_spring3.x\\spring3_learning\\WebRoot\\WEB-INF\\spring3-servlet.xml";
06. Resource res1 = new FileSystemResource(filePath);
07. Resource res2 = new ClassPathResource("WEB-INF\\spring3-servlet.xml");
08. //      Resource res3 = new ServletContextResource(servletContext, "")
09. System.out.println(res1.getFilename());
10. try {
11. System.out.println(res1.getURL());
12. System.out.println(res1.getFile());
13. System.out.println(res2.getFilename());
14. catch (IOException e) {
15. e.printStackTrace();
16. }
17. }
18. }

@上面分别以系统文件路径和类路径读取本地资源文件,常用的是ClassPathResource,这样在工程移植的时候就不会出现路径问题。

SerlvetContextResource:

01. <%@ page language="java" contentType="text/html; charset=utf-8"
02. pageEncoding="utf-8"%>
03. <jsp:directive.pageimport="org.springframework.web.context.support.ServletContextResource"/>
04. <jsp:directive.page import="org.springframework.core.io.Resource"/>
05. <jsp:directive.page import="org.springframework.web.util.WebUtils"/>
06. <%
07. Resource res = new ServletContextResource(application,"/WEB-INF/classes/conf/testFile.txt");
08. out.print(res.getFilename()+"<br/>");
09. out.print(WebUtils.getTempDir(application).getAbsolutePath());
10. %>
@输出结果为:


testFile.txt
A:\Program Files (x86)\Apache Software Foundation\Tomcat 6.0\work\Catalina\localhost\spring3_chapter3

资源加载路径表示:

常用的classpath(值加载第一个包下的资源文件):,classpath*(加载类路径下多个模块多个相同报名的资源文件):

在实际开发中常用的就是classpath路径下加载资源文件了,那么Spring提供了一个强大的资源加载机制,在通过classpath:和file:标示符加载多个资源文件大小的同时,提供了Ant风格:

? :匹配文件名中的一个字符。

*  :匹配文件名中的任意字符。

** :匹配多层路径。

要使用这些Ant风格的方式,就要用到了资源加载器,ResourceLoader:

看一个小实例:

01. public class ResourceUtilsDemo {
02. public static void main(String[] args) {
03. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
04. try {
05. //Ant风格
06. // Resource[] resources = resolver
07. // .getResources("classpath*:/*.xml");
08. // Resource[] resources = resolver
09. // .getResources("classpath*:com/**/*.xml");
10. //Ant只有在调用getResources方法返回多个资源文件的时候使用
11. Resource[] resources = resolver
12. .getResources("classpath*:/?eans.xml");
13. for (Resource resource : resources) {
14. System.out.println(resource.getFilename());
15. }
16. catch (IOException e) {
17. e.printStackTrace();
18. }
19. }
20. }
有了这些基础,回到Spring:
看看BeanFactory的体系结构:

@BeanFactory:提供了getBean,也就是我们常用的

@HierachicalBeanFactory:可以查看Bean的个数,获取Bean的配置名,查看容器是否包某一Bean

@ConfigurableBeanFactory:增强了IoC容器的可定制性,定义了设置类装载器,属性编辑器,容器初始化后置处理器等。

@AutowireCapableBeanFactory:定义了将容器中的Bean按某种规则进行自动装配的方法

@SingletonBeanRegistry:定义了允许在运行期想容器注册单实例Bean的方法。

@BeanDefinitionRegistry:Spring配置文件中的<bean>节点是通过BeanDefinition对象表示,BeanDefinition描述了Bean的配置信息,BeanDefinitionRegistry提供了向容器手工注册BeanDefinition对象的方法。


BeanFactory的应用,看一个小实例

src目录下,beans.xml:

01. <?xml version="1.0" encoding="UTF-8" ?>
02. <beans xmlns="http://www.springframework.org/schema/beans"
03. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
04. xsi:schemaLocation="http://www.springframework.org/schema/beans
05. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
06. <bean id="car" class="com.baobaotao.Car"
07. init-method="myInit"
08. destroy-method="myDestory"
09. p:brand="红旗CA72"
10. p:maxSpeed="200"
11. /> 
12. </beans>
在Java中使用BeanFactory:
01. public class BeanFactoryDemo {
02. public static void main(String[] args) throws Throwable{
03. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
04. Resource res = resolver.getResource("classpath:beans.xml");
05. System.out.println(res.getURL());
06. BeanFactory bf = new XmlBeanFactory(res);
07. System.out.println("init BeanFactory.");
08.  
09. Car car = bf.getBean("car",Car.class);
10. System.out.println("car bean is ready for use!");
11. car.introduce();
12. }
13. }
@BeanFactory#getBean方法在第一次调用时才实例化Bean,并存于缓存中,第二次调用的时候直接从缓存中取。


@DefaultSingletonBeanFactory提供一个Map集合实现的缓存器,用于缓存单实例Bean。


之前说到ApplicationContext是面向开发者的,那么来看看ApplicationContext:

ApplicationContext:

ApplicationContext是对BeanFactory的扩展,使用过程中常用的两个实现类

FileSystemXmlApplicationContext&&ClassPathXmlApplicationContext

ApplicationContext初始化:

01. public class MyApplicationContext {
02.  
03. public static void main(String[] args) {
04. // 获取配置文件
05. ApplicationContext cx = new ClassPathXmlApplicationContext(
06. new String[] { "beans.xml" });//传入数组
07. Person person = cx.getBean("person", Person.class);
08. System.out.println(person);
09. }
10. }
@获取ApplicationContext实例后,可以像BeanFactory一样调用getBean方法了


@ApplicationContext在初始化的时候会实例化所有单例的Bean,非单例的Bean在调用时才实例化,区别在与scope=“singleton/prototype”所以初始化时间比BeanFactory长。

在xml中的监听器配置:

上述是在Java中手动获得ApplicationContext和BeanFactory,那么启动容器时,怎么加载这些配置文件呢?需要在xml中配置一个监听器了:

01. <!-- 加载配置文件的路径信息 -->
02. <context-param>
03. <param-name>contextConfigLocation</param-name>
04. <param-value>/WEB-INF/applicationContext.xml</param-value>
05. <!--<param-value>classpath:applicationContext.xml</param-value> -->
06. </context-param>
07.  
08. <listener>
09. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
10. </listener>

@配置文件路径同样支持Ant风格,监听器是常用的,还有一个通过Servlet自启动来实现。

Spring3新特性:基于Java类提供配置信息:

首先我们提供一个带有@Configuration注解的Java类:

01. /**
02. * 通过java类提供IoC配置信息
03. *
04. * @author PingCX
05. *
06. */
07. @Configuration
08. // 告诉Spring这是一个bean提供类
09. public class Beans {
10. @Bean(name = "user")
11. @Scope("prototype")
12. // 指定空间,默认是singleton,初始化时实例化,prototype在用到时实例化
13. // 定义一个bean
14. public User createUser() {
15. User user = new User();
16. user.setUserName("ysjian");
17. user.setUserId(1001);
18. return user;
19. };
20.  
21. @Bean(name = "dataSource")
22. public BasicDataSource createDataSource() {
23. BasicDataSource dataSource = new BasicDataSource();
24. dataSource.setDriverClassName("com.mysql.jdbc.Driver");
25. dataSource
26. .setUrl("jdbc:mysql://localhost:3306/spring3?userUnicode=true&characterEncoding=UTF-8");
27. dataSource.setUsername("root");
28. dataSource.setPassword("ysjian");
29. return dataSource;
30. }
31.  
32. @Bean(name = "jdbcTemplate")
33. public JdbcTemplate createjJdbcTemplate() {
34. return new JdbcTemplate(createDataSource());
35. }
36.  
37. @Bean(name = "transactionManager")
38. public DataSourceTransactionManager createdDataSourceTransactionManager() {
39. return new DataSourceTransactionManager(createDataSource());
40. }
41.  
42. @Bean(name = "userService")
43. public IUserService createUserService() {
44. return new UserService();
45. }
46.  
47. @Bean(name = "userDao")
48. public IUserDao createUserDao() {
49. return new UserDao();
50. }
51.  
52. @Bean(name = "loginLogDao")
53. public ILoginLogDao createLoginLogDao() {
54. return new LoginLogDao();
55. }
56. }
@这种方式在实例化对象的时候比较灵活的控制。


启动容器,用到了AnnotationApplicationContext:

01. public class AnnotationApplicationContext {
02.  
03. public static void main(String[] args) {
04. //Java类提供的配置信息
05. ApplicationContext ctx = new AnnotationConfigApplicationContext(
06. Beans.class);
07. User user =  ctx.getBean("user",User.class);
08. System.out.println(user);
09. }
10. }
在xml配置文件中的配置:
01. <!-- 使用@Configuration的Java类提供配置信息 -->
02. <context-param>
03. <param-name>contextClass</param-name>
04. <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
05. </context-param>
06. <context-param>
07. <param-name>contextConfigLocation</param-name>
08. <!-- 指定J提供配置信息的Java类 -->
09. <param-value>com.meritit.ysjian.spring3learning.context.Beans</param-value>
10. </context-param>
11.  
12. <listener>
13. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
14. </listener>
@ContextLoaderListener发现contextClass上下文参数,就会使用WebApplicationContext的实现类初始化容器,再根据contextConfigLocation上下文参数指定有@Configuration注解的Java类提供的配置信息初始化容器。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值