Spring是一个开源框架,是一个基于IOC和AOP来架构多层的JavaEE 架构,默认是单例模式

Spring模块分为以下几个部分

1.Core container(核心容器)

含有Core,Beans,Context,和Expression Language

2.Data Access

3.Web

4.AOP

4.Test

IOC

Inversion of Control

public class Girl {
//boy是在应用内部创建及维护的。
private Boy boy =new Boy();
public void kiss() {
System.out.println(boy.getBoyObject());
}
}

IOC(控制反转):所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转,目的是为了获得更好的扩展性和良好的可维护性。

<bean id="boy" class="cn.itcast.a_ioc.Boy"></bean>

DI

(依赖注入):把依赖的对象交给外部容器负责创建,就是在运行期间,有外部容器动态的将依赖对象注入到组件中。

public class Girl {
private Boy boy = null;
public Boy getBoy() {
return boy;
}
//由spring容器注入Boy对象
public void setBoy(Boy boy) {
this.boy = boy;
}
public Girl(){
System.out.println("这是Girl的构造方法");
}
public void kiss(){
System.out.println("Girl的kiss()方法");
boy.displany();
}
}
//把依赖的对象boy 交有外部容器动态创建并注入
<bean id="boy" class="cn.itcast.b_di.Boy"></bean>
<bean id="girl" class="cn.itcast.b_di.Girl">
<!--
property:用来指定Girl对象中的属性
* name:表示Girl类中属性的名称
* ref:将外部的Boy对象通过set方法注入给Girl对象
-->
<property name="boy" ref="boy"></property>
</bean> 

  当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。

<context:annotation-config/>

这个配置隐式注册了多个对注解进行解析处理的处理器
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor

核心实现类

DefaultListableBeanFactory

DefaultListableBeanFactory是Spring注册及加载Bean的默认实现,主要是对bean注册后的处理

XmlBeanDefinitionReader

InputStreamSource

//通过Resource完成了对配置文件的封装
Resource resource = new ClassPathResource("beanFactoryTest.xml"); public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
} else if (this.classLoader != null) {
is = this.classLoader.getResourceAsStream(this.path);
} else {
is = ClassLoader.getSystemResourceAsStream(this.path);
}
//省略部分代码
}

接口 ApplicationContextInitializer

实现接口的initialize 方法初始化 配置 如reids apollo

XmlBeanFactory

XmlBeanFactory
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader = new XmlBeanDefinitionReader(this);
this.reader.loadBeanDefinitions(resource);
}
XmlBeanDefinitionReader->loadBeanDefinitions->doLoadBeanDefinitions->registerBeanDefinitions 

实例化bean

AbstractApplicationContext->getBean->doGetBean
 protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
// 提取对应的bean名称
String beanName = this.transformedBeanName(name);
//检查缓存中或者实例工厂中是否有对应的实例(因为可能有循环依赖的情况,所有在创建bean是 如有有依赖上一个bean的则直接使用ObjectFactory
//直接尝试从缓存中或者SingletonFactories的ObjectFactory中获取
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isDebugEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
} //返回对应的实例,返回实例本身或者指定方法返回的实例
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//检查是否有循环依赖,只有单例才会尝试解决循环依赖,其他直接报错
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
} BeanFactory parentBeanFactory = this.getParentBeanFactory();
//beanDefinitionMap中(所以已经加载的类中如果不包含从parentBeanFactory中检测
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
//递归到BeanFactory中寻找
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
} return parentBeanFactory.getBean(nameToLookup, requiredType);
}
//记录不是做类型检查,记录要创建的bean
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
} try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//若存在依赖则需要递归实例化依赖的 bean
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//缓存依赖调用
this.registerDependentBean(dep, beanName); try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
// 依赖的bean实例完后,开始实例化mbd本身
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
// prototype 模式的创建(new)
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
} bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 指定的 scope上实例化bean(添加@Scope注解的)
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
} try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName); Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
} return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
//检查需要的类型是否符合bean的实际类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
} throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}

  

注解

Autowired

//@Autowired @Qualifier("userDao1")
private IUserDao userDao;

Autowired标注在字段上
如果Autowired注解标注在字段上,会按照IUserDao的类型找,找不到抛出异常。
Autowired @Qualifier("userDao")标注在字段上
如果@Autowired @Qualifier("userDao")标注在字段上,按照名称userDao找,如果没有找到,此时会抛出异常。

Resource

Resource注解标注在字段上
如果@Resource注解标注在字段上, 此时先按照属性的名称找,找不到在根据属性类型找,都没找到就抛异常。
@Resource(name="userDao")标注在字段上,根据name找,找不到就抛异常。

Spring (一)的更多相关文章

  1. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  2. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  3. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  4. [Spring]IoC容器之进击的注解

    先啰嗦两句: 第一次在博客园使用markdown编辑,感觉渲染样式差强人意,还是github的样式比较顺眼. 概述 Spring2.5 引入了注解. 于是,一个问题产生了:使用注解方式注入 JavaB ...

  5. 学习AOP之透过Spring的Ioc理解Advisor

    花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...

  6. 学习AOP之深入一点Spring Aop

    上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...

  7. 学习AOP之认识一下Spring AOP

    心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...

  8. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  9. Spring之旅(2)

    Spring简化Java的下一个理念:基于切面的声明式编程 3.应用切面 依赖注入的目的是让相互协作的组件保持松散耦合:而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件. AOP面向切面 ...

  10. Spring之旅

    Java使得以模块化构建复杂应用系统成为可能,它为Applet而来,但为组件化而留. Spring是一个开源的框架,最早由Rod Johnson创建.Spring是为了解决企业级应用开发的复杂性而创建 ...

随机推荐

  1. flask框架----上下文管理

    一.上下文管理相关知识点: a.类似于本地线程 创建Local类: { 线程或协程唯一标识: { 'stack':[request],'xxx':[session,] }, 线程或协程唯一标识: { ...

  2. QQ项目

    QQ第一部分: 1.数据库 每一个QQ账户必须有  a. state:是否上线的状态  b. IP:正在上线的主机的IP  c. port:UDP端口号(用这个和别的好友通讯)  注:TCP连接时,在 ...

  3. Maven配置阿里云镜像仓库

    配置文件:D:\MyDev\Maven\apache-maven-3.0.5\conf\settings.xml <mirrors> <mirror> <id>al ...

  4. 计算概论(A)/基础编程练习(数据成分)/3:整数的个数

    #include<stdio.h> int main() { ] = {}; // 输入k个正整数 scanf("%d",&k); // 循环读入和进行算术 w ...

  5. 【react】兄弟组件的通信方式,传统非redux

    很多用过redux开发的朋友们都知道,一般兄弟组件通信可以使用redux. redux也是近期在挤时间学习中.可能也不是很懂,说不定是有错误的理解,若有.现在虽然自己搭建了一个react+router ...

  6. 【js】手机浏览器端唤起app,没有app就去下载app 的方法

    这种功能的作用: 1.一般公司有自己的app,而app是需要不断有新用户涌入才能持续运营,达到不错的收入.就需要使用这种方式进行引入新的用户. 2.一些内容在网页端体验不好,或者一些功能需要app内才 ...

  7. SVN的标准目录结构

    SVN目录规范 在visualSVN中创建仓库时,可以选择svn目录结构 Trunk主干目录,此目录下的文件为基准文件. Brancher 用于开发的分支目录 Tags用于发布的版本目录 假设有一个项 ...

  8. php中session同ip不同端口的多个网站session冲突的解决办法

    在局域网内使用IP加端口的访问方式搭了两个相同程序的站,结果发现用户在一个站下登录后,在另一个站也同时登录了,在一个退出后,另一个站也同时退出了.看了下程序发现两个站都是使用纯session方式记录登 ...

  9. 【题解】bzoj 4327 JSOI2012 玄武密码

    原题传送门 我们先对所有询问串建立AC自动机(今天洛咕上有人分不清AC自动机和自动AC机) 然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针所能到的所有前缀都是匹配成功的,暴力向 ...

  10. Vue 中的动画特效

    Vue 中的动画特效 CSS 实现标签显隐 <!DOCTYPE html> <html lang="en"> <head> <meta c ...