1、BeanFactory接口

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType; public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
// getBean()方法从容器中返回Bean
Object getBean(String var1) throws BeansException; <T> T getBean(String var1, Class<T> var2) throws BeansException; Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
// 容器里有没有一个Bean
boolean containsBean(String var1);
// 一个Bean是不是单例的
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
// 一个Bean是不是复例的
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException; Class<?> getType(String var1) throws NoSuchBeanDefinitionException; String[] getAliases(String var1);
}

BeanFactory的子接口ListableBeanFactory

package org.springframework.beans.factory;

import java.lang.annotation.Annotation;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType; public interface ListableBeanFactory extends BeanFactory {
// BeanDefinition
boolean containsBeanDefinition(String var1);
// BeanDefinition
int getBeanDefinitionCount();
// BeanDefinition
String[] getBeanDefinitionNames(); String[] getBeanNamesForType(ResolvableType var1); String[] getBeanNamesForType(Class<?> var1); String[] getBeanNamesForType(Class<?> var1, boolean var2, boolean var3); <T> Map<String, T> getBeansOfType(Class<T> var1) throws BeansException; <T> Map<String, T> getBeansOfType(Class<T> var1, boolean var2, boolean var3) throws BeansException; String[] getBeanNamesForAnnotation(Class<? extends Annotation> var1); Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> var1) throws BeansException; <A extends Annotation> A findAnnotationOnBean(String var1, Class<A> var2) throws NoSuchBeanDefinitionException;
}

BeanFactory的子接口HierarchicalBeanFactory  [ˌhaɪəˈrɑːkɪkl] 

通过这个接口Spring的IoC容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的Bean,但父容器不能访问子容器中的Bean。

package org.springframework.beans.factory;

public interface HierarchicalBeanFactory extends BeanFactory {
// 获得父级的BeanFactory
BeanFactory getParentBeanFactory(); boolean containsLocalBean(String var1);
}

AutowireCapableBeanFactory接口

定义了自动装配

DefaultSingletonBeanRegistry接口

DefaultSingletonBeanRegistry里有一个addSingleton()方法,会把单例的Bean保存到一个ConcurrentHashMap

    // 缓存到一个map里
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256); protected void addSingleton(String beanName, Object singletonObject) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
// 添加单对象到map
this.singletonObjects.put(beanName, singletonObject != null ? singletonObject : NULL_OBJECT);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

DefaultListableBeanFactory 实现类

这个类实现了上面所有的接口

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="tank" class="my.Tank"></bean> </beans>
package my;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import java.io.IOException; public class MyTest {
public static void main(String[] args) throws IOException {
// 创建一个资源加载器
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 使用ClassPathResource加载配置文件
Resource resource = resolver.getResource("classpath:my.xml"); // 创建一个BeanFactory的对象
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource); // 单例的Bean已经缓存到容器中
Tank tank = (Tank)factory.getBean(Tank.class);
tank.run();
}
}
class Tank {
public void run() {
System.out.println("run...");
}
}

3、ApplicatContext接口

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}

ApplicationContext继承了ListableBeanFactory、HierarchicalBeanFactory,另外还通过其它几个接口扩展了BeanFactory的功能。

ApplicationEventPublisher让spring容器拥有发布事件的功能,包括spring容器启动、关闭。ApplicationContext基于Observer模式(java.util包中有对应实现),提供了针对Bean的事件传播功能。事件传播的一个典型应用是,当Bean中的操作发生异常(如数据库连接失败),则通过事件传播机制通知异常监听器进行处理。

ResourcePatternResolver,所有的ApplicationContext实现类都实现了类似于PathMatchingResourcePatternResolver的功能,可以通过文件路径装载spring配置文件。

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import java.io.IOException; public class MyTest {
public static void main(String[] args) throws IOException {
// 使用ClassPathXmlApplicationContext可以省略路径字符串的classpath前缀
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:my.xml");
//AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Tank tank = context.getBean(Tank.class); tank.run();
}
}
class Tank {
public void run() {
System.out.println("run...");
}
}
@Configuration
class MyConfig{
@Bean
public Tank tank() {
return new Tank();
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="tank" class="my.Tank"></bean> </beans>

4、WebApplicationContext

WebApplicationContext是专门为web应用准备的。

WebApplicationContext源码:

package org.springframework.web.context;

import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext; public interface WebApplicationContext extends ApplicationContext {
/**
* WebApplicationContext作为属性保存到了ServletContext中,Spring为此专门提供了一个工具类WebApplicationContextUtils,
* 通过该类的getWebApplicationContext(ServletContext sc)方法,可以从ServletContext中获取WebApplicationContext的实例。
*
* 常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE是在ServletContext中保存WebApplicationContext的key
* 可以通过以下方法获得WebApplicationContext的实例
* WebApplicationContext context =
* (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
*
* 这也正是WebApplicationContextUtils的getWebApplicationContext(ServletContext sc)方法的内部实现方式。
*/
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
/**
* 在非web应用的环境下,Bean只有singleton和prototype两种作用域。
* WebApplicationContext为Bean添加了三个新的作用域:
* 分别是request、sesseion和global sesseion。
*/
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
String SCOPE_GLOBAL_SESSION = "globalSession";
String SCOPE_APPLICATION = "application";
String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
// 也可以WebApplicationContext中获取ServletContext
ServletContext getServletContext();
}

ConfigurableWebApplicationContext源码:

package org.springframework.web.context;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import org.springframework.context.ConfigurableApplicationContext; public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":"; String SERVLET_CONFIG_BEAN_NAME = "servletConfig"; void setServletContext(ServletContext var1); void setServletConfig(ServletConfig var1); ServletConfig getServletConfig(); void setNamespace(String var1); String getNamespace();
// 设置配置文件地址,允许通过配置文件实例化WebApplicationContext
void setConfigLocation(String var1); void setConfigLocations(String... var1); String[] getConfigLocations();
}

XmlWebApplicationContext、AnnotationConfigWebApplicationContext这两个类都实现了上面的接口

但WebApplicationContext的初始化方式和BeanFactory、ApplicationContext不一样,因为它们必须在拥有Web容器的前提下才能启动。使用XmlWebApplicationContext或AnnotationConfigWebApplicationContext实例化WebApplicationContext需要在web.xml中定义监听器ContextLoaderListener。ContextLoaderListener通过ServletContext参数contextConfigLocation获取Spring配置文件的位置,用户可以指定多个配置文件,用逗号、空格或冒号分隔均可。

package com.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.WebApplicationContext; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/run")
public class MyTest extends HttpServlet {
private Tank tank; public void setTank(Tank tank) {
this.tank = tank;
} protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
WebApplicationContext context = (WebApplicationContext) req.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
MyTest myTest = context.getBean(MyTest.class);
myTest.tank.run();
}
}
class Tank {
public void run() {
System.out.println("run ...");
}
}
@Configuration
class MyConfig {
// 这个方法随便声明、方法参数随便写,因为这是一个新的方法,在这个方法的内部调用其它方法
@Bean
public MyTest myTest(Tank tank) {
MyTest myTest = new MyTest();
myTest.setTank(tank);
return myTest;
}
@Bean
public Tank tank() {
return new Tank();
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="tank" class="com.test.Tank"/> <bean id="myTest" class="com.test.MyTest" p:tank-ref="tank"/> </beans>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>spring-demo</display-name>
<!--让spring使用AnnotationConfigWebApplicationContext而非XmlWebApplicationContext启动容器
如果想使用XmlWebApplicationContext,不需要下面这个<context-param>的配置
-->
<!--<context-param>-->
<!--<param-name>contextClass</param-name>-->
<!--<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>-->
<!--</context-param>-->
<context-param>
<param-name>contextConfigLocation</param-name>
<!--<param-value>com.test.MyConfig</param-value>-->
<param-value>classpath:/my.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.test.spring</groupId>
<artifactId>spring-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <name>spring-demo</name> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
</dependencies> <build>
<finalName>spring-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>80</port>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

spring容器、BeanFactory、ApplicatContext、WebApplicationContext的更多相关文章

  1. 获取spring容器上下文(webApplicationContext)的几种方法

    在很多情况,我们需要先获取spring容器上下文,即webApplicationContext,然后通过webApplicationContext来获取其中的bean.典型的情况是,我想在一个并未委托 ...

  2. 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean

    7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...

  3. spring容器BeanFactory简单例子

    在Spring中,那些组成你应用程序的主体及由Spring Ioc容器所管理的对象,都被称之为bean.简单来讲,bean就是Spring容器的初始化.配置及管理的对象.除此之外,bean就与应用程序 ...

  4. BeanFactory到WebApplicationContext的结构 以及bean和spring容器的关系

    BeanFactory: Ioc 容器 ApplicationContext: Spring容器 WebApplicationContext需要ServletContext实例,也就是说它必须在拥有W ...

  5. [原创]java WEB学习笔记98:Spring学习---Spring Bean配置及相关细节:如何在配置bean,Spring容器(BeanFactory,ApplicationContext),如何获取bean,属性赋值(属性注入,构造器注入),配置bean细节(字面值,包含特殊字符,引用bean,null值,集合属性list map propert),util 和p 命名空间

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  7. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  8. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  9. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

随机推荐

  1. OpenGL ES: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  2. ubuntu 16.04下源码安装opencv3.4

    源码安装opencv,遇到了一些小波折,这里做个备忘吧. 首先要下载源码,路径: https://github.com/opencv/opencv 下载成功后,在opencv的根目录下执行下面操作: ...

  3. Win10下音频设备无法播放音乐问题定位

    最近一直在调试音频设备,由于音频设备需要在不同的采样率下面转换,所以会经常导致我的win10无法播放和录音. 刚开始在网上搜了相关的知识,但是一直没找到有效的解决方案.后来,无奈之下,使用了微软的声音 ...

  4. Liferay7 BPM门户开发之19: 理解Service Builder体系

    Service Builder是Liferay为业务开发而设计的模型驱动(model-driven)平台工具,提供一系列的实体类.数据持久化.服务相关的代码自动生成服务.支持Hibernate and ...

  5. js学习笔记----JavaScript中DOM扩展的那些事

    什么都不说,先上总结的图~   Selectors API(选择符API) querySelector()方法 接收一个css选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null ...

  6. Jenkins系列之二——centos 6.9 + JenKins 安装

    centos 6.9 + JenKins 安装记录环境: [root@localhost ~]# cat /etc/issue CentOS release 6.9 (Final) Kernel \r ...

  7. Linux编程 4 (创建文件touch,复制文件cp,tab补全,链接文件ln)

    一.创建文件 使用touch 可以创建空文件,例如opt目录下创建test2.txt文件.这种一般是有些程序必须要先创建文件,才能使用. 二. 复制文件 2.1 使用cp命令来复制文件,需要两个参数- ...

  8. 解决Windows英文版中文软件乱码的问题

    由于工作的原因,我们的开发环境都是基于英文的,但是在打开一些基于中文编码的软件的时候经常会出现乱码的情况.其实只要打开控制面板按照下面的步骤稍微设置一下,就可以完美的在英文操作系统下支持中文软件了,因 ...

  9. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

  10. c# 键值数据保存XML文件

    /// <summary> /// 键值数据保存XML文件 /// </summary> /// <param name="fileName"> ...