目录spring接口介绍Spring事务管理高层抽象主要包括3个接口PlatformTransactionManagerTransactionDefinitionTransationStatus事务传播行为Spring支持两种方式事务管理-编程式的事务管理-使用XML配置声明式事务spring的事务管理主要有:-spring事务管理的一组API-spring的编程式事务管理-spring的声明式事务管理什么是事务?事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败spring接口介绍Spring事务管理高层抽象主要包括3个接口PlatformTransactionManager平台
在Servlet3.0之前,Servlet采用Thread-Per-Request的方式处理请求。即每一次Http请求都由某一个线程从头到尾负责处理。如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成,而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题,即便是像Spring、Struts这样的高层框架也脱离不了这样的桎梏。因为他们都是建立在Servlet之上的。为了解决这个问题,Servlet3.0引入了异步处理,然后在Servlet3.1中又引入了非阻塞IO来进
在xml中的配置1、@EnableWebMvc:开启SpringMVC定制配置功能;在AppConfig中添加@EnableWebMvc注解:通知开启springMvc继承WebMvcConfigurerAdapter创建jsp页面创建success方法启动服务器修改运行:发现图标显示不出来可以看到没有映射到mapping修改运行:自定义添加拦截器创建MyFirstInterceptor实现HandlerInterceptor接口修改拦截任意请求启动服务器:看到我们自定义的拦截器生效了。
创建新的项目,设置不需要web.xml导入jar包provided在打war包的时候就不会将该包导入进去(在tomcat里面已经包含了)spring官方文档中配置以上两种方式都是一样的,这是我们之前整合spring与springMvc的时候配置的一些参数,现在我们采用注解的方式来配置我们之前提过web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servletContainerInitializer(而我们导入的spring-web里面已经帮我们配置好了)我们可以看到它指定了对于的初始化servlet这个类实现了ServletContainerInit
在传统的方式写动态网站的时候需要将servlet配置到xml中,如今可以直接通过spring注解的方式来处理创建HelloServlet类继承HttpServlet启动服务器(这个是什么我什么配置文件都没有,连web.xml都不存在):创建一个页面根据官方文档配置创建MyServletContainerInitializer类继承ServletContainerInitializer在应用启动的时候,会运行onStartup方法ServletContextarg1:代表当web应用的ServletContext:一个Web应用对应一个ServletContext必须将文件javax.servl
分析IOC容器最主要的还是通过观察refresh()方法,在refresh是整个IOC容器的核心刷新前的预处理工作if里面打印的是日志初始化属性配置进行属性校验保存事件获取bean工厂进行BeanFactory的准备工作BeanFactory初始化之后进行的后置处理工作。执行BeanFactoryPostProcessor;BeanFactoryPostProcessor:beanFactory的后置处理器。在BeanFactory标准化初始化之后执行的继续分析按照类型获取所有的postProcessor组件前面所讲的都是对beanfactory的初始化处理,接下来分析对bean的处理注册Be
在spring的IOC容器中,我们是采用什么数据结构来封装Bean的呢?我们可以先假设:因为bean是不可重复的,所以应该采用不可重复的数据结构来存储,这样的话应该采用的是HashSet和hashmap,但是hashset存储的只是对象,而hashmap存储键值对,所以我感觉还是hashmap开始证明自己的想法:首先我是从从ApplicationContext入手的反正我一下没有找到在哪,后来我用另外一个BeanDefinitionRegistry:该类是管理bean的看到getBeanDefinitionCount()查看它的子实现找到了底层存储采用的是ConcurrentHashMap,一
声明式事务接上一个程序,导入jar包(支持spring对数据库的控制)创建TxConfig类解释:调用dataSource()获取数据源,但是由于这是一个配置类,这初始化之后,在调用该配置类中的方法,都是去IOC容器中获取已经初始化的bean,不会再创建一个新的创建UserDao类创建UserService类添加包扫描:实现测试代码如果在进行sql操作的时候报错,它还是会修改数据库,不会进行事务的回滚事务回滚注解。使用@Transactional表示当前方法是一个事务方法然后在加上@EnableTransactionManagement,开启基于注解的事务管理功能然后在配置类中将注册事务管理器
AOP(动态代理):指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方法;导入AOP模块jar包创建一个业务逻辑类MathCalculator,实现一个简单的除法要实现的业务:在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常等等)创建LogAspects类通知方法:前置通知(@Before):logStrat:在目标方法(div)运行之前运行后置通知(@After):logEnd:在目标方法(div)运行结束之后运行返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行异常通知(@AfterThrowin
@Profile:spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;简单来说就是:可以根据不同的开发环境、测试环境、生产环境,实现动态的切换不同的开发环境、测试环境、生产环境;引入相关ar包创建配置类MainConfigOfProfile创建配置文件properties:将配置文件加载进来测试环境下的数据源开发环境下的数据源生产环境下的数据源密码的话我们换一种方式:测试环境开发环境生产环境:对于驱动类Driver我们也可以采用另外一种方式动态获取在bean中分别取上id名测试打印所有的bean运行:现在我们根据某种环境来激活某个数据源Profile注解标识可以随意写注
自动装配:1、@Autowired的使用创建MainConfigOfAutowired类在service层中自动装配创建IOCTest_Autowired类运行:对比两个一样的类实现两个bean它的bean=“BookDao”通过注解@Qualifier()指定使用的id名现在删掉相关的bean配置,然后设置required=false,这样不会出现找不到相应的bean而报null异常对于@Qualifier()注解还是非常的不方便使用@Primary,相当于首选项不过在上面的基础上明确指定使用@Qualifier(),那就选择@Qualifier()中的@Autowired不仅可以使用在变量
接下来分析bean的属性赋值创建MainConfigOfPropertyValues创建测试类打印person的bean运行:在传统的方式中我们在xml中配置使用前面两种赋值方式第三种${}赋值方式:创建properties文件写入在传统的xml方式中,添加外部的文件现在通过注解的方式,原理是一样的查看它的源码添加类路径下的properties传入名字运行:不仅可以通过value获取值,还可以通过environment获取key值
bean的生命周期:bean创建---初始化---销毁的过程容器管理bean的生命周期;我们可以自定义初始化和销毁方法;容器在bean进行当前生命周期的时候来调用我们自定义的初始化和销毁方法1)指定初始化和销毁方法:注解参数中指定init-method和destroy-method=“”创建Car类创建配置类@Configuration加入car的bean方法创建IOCTest_LifeCycle类运行:总结:构造(对象创建)单实例:懒汉式:在被调用的时候创建,单例饿汉式:在容器启动的时候创建多实例:在每次获取的时候创建对象,而且是多例既然我们之前在car类中创建了销毁方法、初始化方法,那我们
给容器中注册组件:1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)2)、@Bean[导入的第三方包里面的组件]例如:3)、@Import[快速的给容器中导入一个组件]创建Color类添加@Import(),直接将Color类(也就是相当于不需要在类的上面加上任何注解)注入进来运行:注意:导入组件,id默认是组件的全类名创建Red再加入到Red.class运行:使用注解ImportSelector查看ImportSelector源码:返回需要导入的组件的全类名数组创建MyImportSelector实现ImportSelecto
Spring单例模式中的懒汉模式和饿汉模式的区别懒加载(单例模式的懒汉模式):单例实例bean:默认在容器启动的时候创建对象;懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化。接上一个程序:在默认情况下启动容器:启动测试类运行:默认情况下,在容器的初始化的时候就已经将所以的bean都加载进去了,这就是设计模式中单例设计模式的饿汉模式。添加注解@Lazy运行:这就是在调用的时候才创建单例,该模式就是设计模式中单例模式的懒汉式修改Test类,看懒加载是不是单例:运行:分析注解@Conditional现在在MainConfig2类中创建两个bean实例同样获取配置类中所有的b
接上一章自定义过滤规则类MyTypeFilter获取当前注解的信息如果注解id包含“er”,就包括进来在MainConfig添加自定义的过滤规则运行:对于person,已经配置好了我们可以看到我们并没有增加什么注解,但是他也被扫描进去了包结构创建配置类创建测试类IOCTest:运行:注意在bean中的对象都是单例模式我们可以测试一下看这两个对象是否相等运行结果那我们能不能改变它的单例模式呢回到测试类,添加注解进入到scope源码当中对于我们来说只需要关注前面两个配置就行了,一个多例和一个单例在运行一次我们可以看到不一样了其实也就相当于在bean上面配置scope那bean的调用时机是什么时候呢
接上一章回到MainConfig类中,根据以往xml的配置我们知道,它是可以指定扫描哪些,不扫描哪些excludeFilters:排除过滤器我们查看@ComponentScan注解源码,看到excludeFilters()方法返回的是Filter数组需要排除的注解:选择排除的方式ANNOTATION:注解排除;ASPECT:ASPECT表达式排除;Assignable:按照类型排除;CUSTOM:自定义排除;REGEX:正则表达式排除;其Filter的源码底层:我们按照注解排除:ComponentScan中的classes源码:由于Class是数组类型,我们可以直接在classes中多写几个当
首先声明该系列不适合零基本的程序员浏览!总体系列流程总体分析Spring注解驱动开发:容器:AnnotationConfigapplicationContext组件添加组件赋值组件注入AOP声明式事务扩展原理:BeanFactoryPostProcesorBeanDefinitionRegistryPostProcessorApplicationListenerSpring容器创建过程Web:servlet3.0异步请求容器注解开发创建相关maven项目:添加spring的相关jar包在我们古老的开发模式中,我们采用的是在xml中写bean的方式注入创建一个person类在我们古老的方式中我们
bean的转换过程下面这张图演示了一个可用的bean是如何从xml配置文件中演变过来的。ApplicationContext的架构图loadBean的全流程getBean的全流程
上篇博客只是对ApplicationContext相关的接口做了一个简单的介绍,作为一个高富帅级别的Spring容器,它涉及的方法实在是太多了,全部介绍是不可能的,而且大部分功能都已经在前面系列博客中做了详细的介绍,所以这篇博问介绍ApplicationContext最重要的方法(小编认为的):refresh()。refresh()是定义在ConfigurableApplicationContext类中的,如下:/***Loadorrefreshthepersistentrepresentationoftheconfiguration,*whichmightanXMLfile,properti
在前面30多篇博客中都是基于BeanFactory这个容器来进行分析的,BeanFactory容器有点儿简单,它并不适用于我们生产环境,在生产环境我们通常会选择ApplicationContext,相对于大多数人而言,它才是正规军,相比于BeanFactory这个杂牌军而言,它由如下几个区别:继承MessageSource,提供国际化的标准访问策略。继承ApplicationEventPublisher,提供强大的事件机制。扩展ResourceLoader,可以用来加载多个Resource,可以灵活访问不同的资源。对Web应用的支持。ApplicationContext下图是Applicati
在分析SpringBean实例化过程中提到Spring并不是一启动容器就开启bean的实例化进程,只有当客户端通过显示或者隐式的方式调用BeanFactory的getBean()方法来请求某个实例对象的时候,它才会触发相应bean的实例化进程,当然也可以选择直接使用ApplicationContext容器,因为该容器启动的时候会立刻调用注册到该容器所有bean定义的实例化方法。当然对于BeanFactory容器而言并不是所有的getBean()方法都会触发实例化进程,比如signleton类型的bean,该类型的bean只会在第一次调用getBean()的时候才会触发,而后续的调用则会直接返回
spring.profiles.active和@Profile这两个我相信各位都熟悉吧,主要功能是可以实现不同环境下(开发、测试、生产)参数配置的切换。其实关于环境的切换,小编在博客【死磕Spring】-----IOC之PropertyPlaceholderConfigurer的应用已经介绍了利用PropertyPlaceholderConfigurer来实现动态切换配置环境,当然这种方法需要我们自己实现,有点儿麻烦。但是对于这种非常实际的需求,Spring怎么可能没有提供呢?下面小编就问题来对Spring的环境&属性来做一个分析说明。概括Spring环境&属性由四个部分组成:
将定义bean的资源文件解析成BeanDefinition后需要将其注入容器中,这个过程由BeanDefinitionRegistry来完成。BeanDefinitionRegistry:向注册表中注册BeanDefinition实例,完成注册的过程。下图是BeanDefinitionRegistry类结构图:BeanDefinitionRegistry继承了AliasRegistry接口,其核心子类有三个:SimpleBeanDefinitionRegistry、DefaultListableBeanFactory、GenericApplicationContext。AliasRegistr
在开始分析InstantiationStrategy之前,我们先来简单回顾下bean的实例化过程:bean的创建,主要是AbstractAutowireCapableBeanFactory.doCreateBean(),在这个方法中有bean的实例化、属性注入和初始化过程,对于bean的实例化过程这是根据bean的类型来判断的,如果是单例模式,则直接从factoryBeanInstanceCache缓存中获取,否则调用createBeanInstance()创建。在createBeanInstance()中,如果Supplier不为空,则调用obtainFromSupplier()实例化bea
在实例化bean阶段,我们从BeanDefinition得到的并不是我们最终想要的Bean实例,而是BeanWrapper实例,如下:所以这里BeanWrapper是一个从BeanDefinition到Bean直接的中间产物,我们可以称它为”低级bean“,在一般情况下,我们不会在实际项目中用到它。BeanWrapper是Spring框架中重要的组件类,它就相当于一个代理类,Spring委托BeanWrapper完成Bean属性的填充工作。在bean实例被InstantiatioonStrategy创建出来后,Spring容器会将Bean实例通过BeanWrapper包裹起来,是通过BeanW
在上篇文章中小编分析了SpringConversionService类型转换体系,相信各位都对其有了一个清晰的认识,这篇博客将利用ConversionService体系来实现自己的类型转换器。ConversionService是Spring类型转换器体系中的核心接口,它定义了是否可以完成转换(canConvert())与类型转换(convert())两类接口。ConversionService有三个子类,每个子类针对不同的类型转换:Converter<S,T>:将S类型对象转为T类型对象。GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型
我们知道不管bean对象里面的属性时什么类型,他们都是通过XML、Properties或者其他方式来配置这些属性对象类型的。在Spring容器加载过程中,这些属性都是以String类型加载进容器的,但是最终都需要将这些String类型的属性转换Bean对象属性所对应真正的类型,要想完成这种由字符串到具体对象的转换,就需要这种转换规则相关的信息,而这些信息以及转换过程由Spring类型转换体系来完成。我们依然以xml为例,在Spring容器加载阶段,容器将xml文件中定义的<bean>解析为BeanDefinition,BeanDefinition中存储着我们定义一个bean需要的所
在文章【死磕Spring】-----IOC之深入分析BeanFactoryPostProcessorz中提到,BeanFactoryPostProcessor作用与bean完成加载之后与bean实例化之前,是Spring提供的一种强大的扩展机制,他有两个重要的子类,一个是PropertyPlaceholderConfigurer,另一个是PropertyOverrideConfigurer,其中PropertyPlaceholderConfigurer允许我们通过配置Properties的方式来取代bean中定义的占位符,而PropertyOverrideConfigurer呢?正是我们这篇博
在博客【死磕Spring】-----IOC之深入分析PropertyPlaceholderConfigurer中了解了PropertyPlaceholderConfigurer内部实现原理,她允许我们在XML配置文件中使用占位符并将这些占位符所代表的资源单独配置到简单的properties文件中来加载。这个特性非常重要,因为它我们对Bean实例属性的配置变得非常容易控制了,主要使用场景有:动态加载配置文件,多环境切换属性加解密下面我们就第一个应用场景来做说明。利用PropertyPlaceholderConfigurer实现多环境切换在我们项目开发过程中,都会存在多个环境,如dev、test、