spring 源码-context

1 spring-context 模块概要
该模块主要实现在spring-beans 模块的扩展,主要对aop支持及el表达式的实现
在这里插入图片描述
分析示例

  public static void main(String[] args){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");TestBean testBean = (TestBean) context.getBean("testBean");testBean.test();System.out.println(testBean);}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd"><aop:aspectj-autoproxy proxy-target-class="false"/><bean id="testBean" class="com.xie.java.aop.TestBean"/><bean id="aspectJTest" class="com.xie.java.aop.AspectJTest"/>
</beans>

从ClassPathXmlApplicationContext 入手,先看下该类的继承结构

在这里插入图片描述
2 applicationcontext 初始化
从上面来看该类继承还是非常复杂的,不管怎么样,先从调用的地方入手

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {this(configLocations, true, null);}public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);//处理配置资源初始化setConfigLocations(configLocations);if (refresh) {//这是真正的核心入口refresh();}}

上面都是一些非常简单的代码,无需多解释,接下来主要是看AbstractApplicationContext.refresh方法,context 绝大部分功能由AbstractApplicationContext去实现,下面是主线实现代码,包括利用beanfactory加载beandefinitions 及实例化这些beans 以及aop的实现

    @Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新前一些准备prepareRefresh();//获得beafactory,并加载beandefinitionConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//准备一下beanfactory的信息prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.//调用beanfactoryPostProcessorsinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.//注册bean processors 用于拦截bean的创建registerBeanPostProcessors(beanFactory);// Initialize message source for this context.//初始化容器消息源initMessageSource();// Initialize event multicaster for this context.//初始化事件广播者initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.//初始化子容器其它特定beans onRefresh();// Check for listener beans and register them.//注册监听者registerListeners();// Instantiate all remaining (non-lazy-init) singletons.//实例化所有拥有非懒加载的单例finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.//最后一步,发布对应的事件finishRefresh();}//省略一些代码}}
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}@Overrideprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {//创建beafactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);//加载beandefinitions loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.//创建xml beandefinition readerXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);//通过xml reader 读取xml配置文件 loadBeanDefinitions(beanDefinitionReader);}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {Resource[] configResources = getConfigResources();if (configResources != null) {reader.loadBeanDefinitions(configResources);}//获得所有配置资源String[] configLocations = getConfigLocations();if (configLocations != null) {//正式通过xmlreader解释xml 配置,并把解释到的beandedinition//注册到beanfactory里,接下来就是beans模块已讲过的了reader.loadBeanDefinitions(configLocations);}}

3 预实例化beanfactory里单例对象
接下要分析如何把上面得到的beandefinitions 进行实例化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {//省略一大波代码// Instantiate all remaining (non-lazy-init) singletons.//预实例化单例,beanFactory.preInstantiateSingletons();
}

获取beanfactory里所有beanNames进行实例化

@Override
public void preInstantiateSingletons() throws BeansException {//获得所有beanNames List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);//逐个遍历,实例化预加载单例对象for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//判断要创建的实例是否为FactoryBeanif (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {//开始他建实例,这块是beans模块内容,不再重述了getBean(beanName);}}}//这里省略一些代码
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

标示符和关键字的总结--希望别再犯错

&#xff08;一&#xff09;Java关键字的表 一共50个关键字&#xff0c;如下表 其中绝大部分关键词是Java语法发布之初就约定好的&#xff0c;少部分关键词是随Java语言发展后加入的。 strictfp JDK1.2 加入 assert JDK1.4 加入 enum JDK5.0 加入 还有少数单词&#xff0c;目前…

历届试题 打印十字图

问题描述 小明为某机构设计了一个十字型的徽标&#xff08;并非红十字会啊&#xff09;&#xff0c;如下所示&#xff1a; ..$$$$$$$$$$$$$....$...........$..$$$.$$$$$$$$$.$$$$...$.......$...$$.$$$.$$$$$.$$$.$$.$...$...$...$.$$.$.$$$.$.$$$.$.$$.$.$...$...$.$.$$.$.$.…

Spring BeanDefinition

BeanDefinition&#xff0c;顾名思义&#xff0c;是一个对象(Bean)在Spring中描述&#xff0c;其核心类图&#xff1a; 从类图我们详细了解BeanDefinition。 BeanDefinition接口继承自BeanMetadataElement和AttributeAccessor两个接口。 BeanMetadataElement&#xff1a;bean…

乐尚网络:小程序商城零售行业10大新赋能

微信小程序上线以来&#xff0c;各行各业积极入场小程序&#xff0c;着手打造属于自己的小程序生态。小程序形态多样&#xff0c;适合你的小程序才是最好的&#xff1b;在众多形态中&#xff0c;小程序商城可以说是零售行业的主体形态了&#xff0c;因为通过平台直接实现交易是…

深度学习中的正则化

正则化方法有如下几种&#xff1a; 一、参数范数惩罚 其中L2、L1参数正则化介绍与关系如下 1、L2 参数正则化 直观解释如下&#xff1a; 2、L1 参数正则化 二、获取更多数据&#xff08;扩样本&#xff09; 避免过拟合的基本方法之一是从数据源获得更多数据&#xff0c;当训练数…

spring uml

spring执行流程&#xff1a; 1&#xff1a; 加载spring.xml文件 2&#xff1a; 创建xml文件解析器 3&#xff1a; 获取命名空间&#xff0c;即在spring.xml文件中的 http://www.springframework.org/schema/context 4&#xff1a; 根据命名空间找到命名空间处理器&#xff0c;在…

「造个轮子」——cicada(轻量级 WEB 框架)

前言 俗话说 「不要重复造轮子」&#xff0c;关于是否有必要不再本次讨论范围。 创建这个项目的主要目的还是提升自己&#xff0c;看看和知名类开源项目的差距以及学习优秀的开源方式。 好了&#xff0c;现在着重来谈谈 cicada 这个项目的核心功能。 我把他定义为一个快速、轻量…

基于owncloud构建私有云储存网盘

注意事项&#xff1a;需要ping通外网 需要LAMP架构yum -y install httpd php php-mysql mariadb-server mariadb sqlite php-dom php-mbstring php-gd php-pdo 开启服务[rootowncloud ~]# setenforce 0setenforce: SELinux is disabled[rootowncloud ~]# systemctl stop firewa…

Spring 源码分析之AbstractApplicationContext源码分析

首先我觉得分析ApplicationContext必须从它的实现类开始进行分析&#xff0c;AbstractApplicationContext我觉得是一个不错的选择&#xff0c;那我们就从这里开始逐一分析吧&#xff0c;首先我自己手画了一张图&#xff0c;作为索引吧&#xff0c;其中蓝色的为类&#xff0c;紫…

[USACO15FEB]Superbull (最小生成树)

题目链接 Solution 基本上就是个板子. 因为 \(n\) 很小,只有 \(2000\),所以直接暴力建图,然后跑最小生成树就好了. Code #include<bits/stdc.h> #define ll long long using namespace std; const int maxn2008; struct sj{int to,fr; ll w; }a[maxn*maxn]; int fa[maxn]…

Java中九大内置对象

1、Request对象 该对象封装了用户提交的信息&#xff0c;通过调用该对象相应的方法可以获取封装的信息&#xff0c;即使用该对象可以获取用户提交的信息。 当Request对象获取客户提交的汉字字符时&#xff0c;会出现乱码问题&#xff0c;必须进行特殊处理。首先&#xff0c;…

ORACLE导出导入意外终止导致 ORACLE initialization or shutdown in progress 问题解决

由于意外情况导致 ORACLE initialization or shutdown in progress 个人理解为主要是归档日志出现问题&#xff0c; 首先cmd 1.sqlplus /nolog 进入sqlplus 2.connect /as sysdba 连接dba 3.shutdown normal 卸载数据库 4.startup mount;重启例程 5.alter database open;开…

Spring中资源的加载ResourceLoader

Spring中资源的加载是定义在ResourceLoader接口中的&#xff0c;它跟前面提到的抽象资源的关系如下&#xff1a; ResourceLoader的源码 public interface ResourceLoader { /** Pseudo URL prefix for loading from the class path: "classpath:" */ String CLAS…

Codeforces Round #540 (Div. 3)(部分题解)

链接:http://codeforces.com/contest/1118 来源:Codeforces 文章目录A. Water BuyingB. Tanya and Candies(前缀和)D1. Coffee and Coursework (Easy version)(贪心)D2. Coffee and Coursework (Hard Version)(二分)A. Water Buying 题意:用最小的花费买到刚好合适的东西.我们可…

集合一些方法陷阱

一&#xff1a;asList 数组转ArrayList陷阱&#xff1a; asList() 源码&#xff1a;public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); } private final E[] a; ArrayList(E[] array) { if (arraynull) throw new NullPointerExcept…

java项目中的classpath

在java项目中&#xff0c;你一定碰到过classpath&#xff0c;通常情况下&#xff0c;我们是用它来指定配置/资源文件的路径。在刚开始学习的时候&#xff0c;自己也糊里糊涂&#xff0c;但是现在&#xff0c;是时候弄清楚它到底是指什么了。 顾名思义&#xff0c;classpath就是…

C++命名空间(namespace)

在c中&#xff0c;名称&#xff08;name&#xff09;可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大&#xff0c;名称互相冲突性的可能性越大。另外使用多个厂商的类库时&#xff0c;也可能导致名称冲突。为了避免&#xff0c;在大规模程序的设计中&#xff…

P1556 幸福的路

题意&#xff1a;平面内有N头牛$N\le 10$john从&#xff08;0,0&#xff09;出发&#xff0c;最后回到(0,0) 只有走到牛那里john才可以改变方向&#xff0c;否则沿着直线走 问john经过每一头牛并且在每一头牛出恰好改变方向一次的方案&#xff08;牛可以经过多次&#xff0c;但…

Class.getResource和ClassLoader.getResource

一案例驱动 二源码分析 三类加载器ClassLoader 四总结 五参考 一案例驱动 最近加载文件的时候遇到了一个问题&#xff0c;很有意思&#xff01; 具体看下面案例代码 public class TestClassLoader {public static void main(String[] args) {System.out.println(TestClassLoad…

spring-6、动态代理(cglib 与 JDK)

JDK动态代理与Cglib动态代理 JDK动态代理: 1.能够继承静态代理的全部优点.并且能够实现代码的复用.2.动态代理可以处理一类业务.只要满足条件 都可以通过代理对象进行处理.3.动态代理的灵活性不强.4.JDK 的动态代理要求代理者必须实现接口, , 否则不能生成代理对象. . 1 packag…