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. KNN算法简介

    KNN算法 K-近邻算法原理 K最近邻(kNN,k-NearestNeighbor)分类算法,见名思意. 我们的目的是要预测某个学生在数学课上的成绩... 先来说明几个基本概念:图中每个点代表一个样本 ...

  2. C# 获取Header中的token值

    public CurrentUser currentUser { get { CurrentUser result = new CurrentUser(); //jwt 解密token IJsonSe ...

  3. ubuntu 16.04 下更换boost版本

    如果是新机器,没装过boost,那么直接一条命令 sudo apt-get install libboost-all-dev 头文件一般安装在 /usr/include 下面有一个目录boost,里面 ...

  4. 机器学习基石笔记:10 Logistic Regression

    线性分类中的是非题------>概率题, 设置概率阈值后,大于等于该值的为O,小于改值的为X.------>逻辑回归. O为1,X为0: 逻辑回归假设: 逻辑函数/S型函数:光滑,单调, ...

  5. tomcat-四种运行模式和三种部署模式(优化)

    四中运行模式如下: 1-bio: 传统的Java I/O操作,同步且阻塞IO. 2-nio: JDK1.4开始支持,同步阻塞或同步非阻塞IO 3-aio(nio.2): JDK7开始支持,异步非阻塞I ...

  6. 通过Anaconda在Ubuntu16.04上安装 TensorFlow(GPU版本)

    一. 安装环境 Ubuntu16.04.3 LST GPU: GeForce GTX1070 Python: 3.5 CUDA Toolkit 8.0 GA1 (Sept 2016) cuDNN v6 ...

  7. (转)你真的会写单例模式吗——Java实现

    http://www.runoob.com/design-pattern/singleton-pattern.html 单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好.用对单例模式, ...

  8. 调试工具Chisel-LLDB插件

    Chisel-LLDB命令插件 相信每个人或多或少都在用LLDB来调试,比如po一个对象.LLDB的是非常强大的,且有内建的,完整的 Python 支持.今天我们主要介绍一个 facebook 开源的 ...

  9. Android生成自定义二维码

    前面说过两种二维码扫描方式,现在说如何生成自定义酷炫二维码.二维码生成需要使用Google开源库Zxing,Zxing的项目地址:https://github.com/ZBar/ZBar,我们只需要里 ...

  10. Linux_CentOS-服务器搭建 <四>

    既然tomcat,弄好了,数据库安装好了.我们考虑考虑下.今天带给大家是, 数据库的还原备份: 备份开始:      登录开始: mysql -u root -p  创建一个测试用的数据库test并创 ...