Spring框架
Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系。其核心就是控制反转(IOC),和面向切面(AOP),简单的说就是一个分层的轻量级开源框架。
轻量、控制反转、面向切面、容器、MVC框架、事务管理、异常处理
构成模块
核心容器:核心容器提供Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文:Spring上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP:通过配置管理特性,SpringAOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI
Spring 原理
1) 建立一个bean类(java实体类):Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象
2) 在applicationContext.xml中配置,bean的配置
3) 主方法中(Main)
//创建IOC容器
当ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext .xml");
Persion persion=(Persion)ac.getbean(“Persion”);//从容器里获取bean实例
//使用bean persion.genBean();
被执行时,Spring容器对象被创建,同时applicationContext .xml中的bean就会被创建到内存中:
原理总结:
1.使用spring ,没有new对象,我们把创建对象的任务交给spring框架。
通过newXmlBeanFactory(“applicationContext.xml”)/ newClassPathXmlApplicationContext("applicationContext .xml")等方式即可启动容器。在容器启动时,Spring根据配置文件的描述信息,自动实例化Bean并完成依赖关系的装配,从容器中即可返回准备就绪的Bean实例,后续可直接使用之。
Spring为什么会有这种“神奇”的力量,仅凭一个简单的配置文件,就能魔法般地实例化并装配好程序所用的Bean呢?这种“神奇”的力量归功于Java语言本身的类反射功能
2.spring实际上是一个容器框架,可以配置各种bean(action/service/domain/dao),并且可以维护bean与bean的关系,当我们需要使用某个bean的时候,我们可以getBean(id),使用即可。
BeanFaction 和applicationContext的区别:Spring提供两种容器
1.Beanfactory,它的核心概念就是bean工厂,用作于bean生命周期的管理,最基本的依赖注入
2.applicationcontext,单看名字(应用上下文)就能看出它包含的范围更广,它继承自bean factory但不仅仅是继承自这一个接口,还有继承了其他的接口,
区别:
1)初始化Bean:
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。
2) ApplicationContext会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而BeanFactory需要在代码中通过手工调用addBeanPostProcessor()方法进行注册
3) BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。
ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能
(1)MessageSource, 提供国际化的消息访问
(2)资源访问,如URL和文件
(3)事件传播特性,即支持aop特性
(4)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 Bean的生命周期
1.Spring容器 从XML 文件中读取bean的定义,并实例化bean。
2.Spring根据bean的定义填充所有的属性。
3.如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
4.如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
5.如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
6.如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
7.如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
8.如果bean实现了 DisposableBean,它将调用destroy()方法
Bean的作用域:通过scope来设置作用域范围
当即“scope”,在面向对象程序设计中一般指对象或变量之间的可见范围。而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。
单例(singleton): bean在每个Spring ioc 容器中只有一个实例
原型(prototype):一个bean的定义可以有多个实例
会话(session):在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效
请求(request):每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
<bean id="userDao" class="com.ioc.UserDaoImpl"scope="singleton"/>
Spring配置bean实例化的方式:3种
1)使用类构造器实例化
2)使用静态工厂方法实例化(简单工厂模式)
3)使用实例工厂方法实例化(工厂方法模式)
IOC:(全称:Inverse Of Control)控制反转:把创建对象和维护之间的关系的权利由程序中转移到Spring容器的配置文件中。
DI: (全称:DependencyInjection)依赖注入,IOC的另一种表现方式,组件以一种预先定义好的方式来接受容器注入的资源。
IOC基础:IoC底层实现:工厂(设计模式)+反射(机制) + 配置文件(xml)
1. 控制反转IoC(Inversion of Control),是一种设计思想,.将Bean 创建反转给Spring容器.
2. 依赖注入DI(Dependency Injection)是实现IoC的一种方法,在Spring创建这个类的过程中,将这个类的依赖的属性注入进去.
DI是通过反射来实现的,反射允许程序通过某个类的名字或者对象来得到类本身。spring就是通过反射来完成注入的。
作用:把应用的代码量降到最低,使应用容易测试。最小的代价和最小的侵入性使松散耦合得以实现
IOC的实现方式:XML配置方式、Spring注解方式
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的
DI(依赖注入)
依赖注入,本质上就是自动进行属性赋值。
原理:创建bean后,需要注入依赖。直接遍历BeanDefinition中定义的属性中,逐个通过反射java.lang.reflect.Field来设置属性值,如果属性值是ref(引用其他bean),则获得其他bean,并给属性赋值
其实依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中,最后它将这个类的实例返回给我们
三种方式:setter方法注入、构造器注入、使用注解(annotation)方式
1.构造器注入,通过
2.setter方法注入, 通过
3.使用Filed注入(用于注解方式)常用
1) 在applicationContext.Xml配置
2) 在配置文件中打开
3)在配置文件中配置bean对象
4)在需要依赖注入的类中,声明一个依赖对象,不用生成该依赖对象的setter方法,并且为该对象添加注解。
注意:使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。
自动装配Autowire
Spring引入Autowire(自动装配)机制就是为了解决
方式:可以配置在
只需要配置一个autowire属性即可完成自动装配,不用再配置文件中写
byame/bytype/construcyer/aotudetect
Spring注解
原因:Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。
使用注解来构造IoC容器
@Component是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。
@Controller对应表现层的Bean,也就是Action(如struts中的action)
@Service对应的是业务层Bean,
@Repository对应数据访问层Bean ,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier("personDaoBean") 存在多个实例配合使用
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
区分一下@Autowired和@Resource两个注解的区别:
(1)、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配
(2)、@Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。
如何自定义注解实现功能
注解的原理:注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。
自定义注解:(4种元注解)
1.@Target:说明Annotation所修饰的对象范围
2.@Retention:说明Annotation的生命周期
3.@Documented:说明将注解包含在Javadoc中
4.@Inherited:允许子类继承父类中的注解
步骤
1.定义注解格式
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Column {String value();}
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他
细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解
Spring中用到的设计模式(9大模式)
1.工厂模式(Factorypattern)
Spring中在各种BeanFactory以及ApplicationContext创建中都用到了典型的工厂方法模式(从xml或者注解加载BeanDefinition,然后实例化对象)
2. 代理模式(Proxy pattern)
Spring的Proxy模式主要在Aop的实现中有体现,比如Jdk动态代理和Cglib动态代理
3.单列模式
spring创建的bean默认为singleton
4.模板模式
spring中很多地方会这样做,在一个方法里面完成了一小部分逻辑,然后接着调用一个或多个抽象方法,而这个抽象方法需要由子类重写,比如AbstractApplicationContext里面的refresh()、getBeanFactory()
AOP(Aspect Oriented Programming):面向切面
一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面
两大部分:核心关注点和横切关注点,业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点
权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
核心概念
1、切面(aspect)
散落在系统各处的通用的业务逻辑代码,如上图中的日志模块,权限模块,事务模块等,切面用来装载pointcut和advice
2、通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
3、连接点(joinpoint)
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
4、切入点(pointcut)
拦截的方法,连接点拦截后变成切入点
6、目标对象(Target Object)
代理的目标对象,指要织入的对象模块,如上图的模块一、二、三
7、织入(weave)
通过切入点切入,将切面应用到目标对象并导致代理对象创建的过程
8、AOP代理(AOP Proxy)
AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理
Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:
1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB
AOP编程其实是很简单的事情,纵观AOP编程,程序员只需要参与三个部分:
1、定义普通业务组件
2、定义切入点,一个切入点可能横切多个业务组件
3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作
所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=增强处理+被代理对象的方法。
AOP通知
通知是个在方法执行前后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码
Spring切面可以应用五种类型的通知:
1.before:前置通知,在一个方法执行前被调用。@Before
2.after: 在方法执行之后调用的通知,无论方法执行是否成功。@After
3.after-returning: 仅当方法成功完成后执行的通知。@AfterReturning
4.after-throwing: 在方法抛出异常退出时执行的通知。@AfterThrowing
5.around: 在方法执行之前和之后调用的通知。@Around
Spring AOP的使用步骤
一、定义具体业务逻辑模块(目标对象)
二、定义切面(即实现通知逻辑)
三、实现切面逻辑
Spring实现Aspectj的步骤
(1)加入jar包:下载aspectj-1.8.9.jar并解压,将lib文件夹中的jar包加入项目;
其实只需要加入三个包:aspectjrt.jar,aspectjweaver.jar(lib文件夹中包含)以及aopalliance.jar(另外下载)
(2)beans.xml中添加支持aspectj的代码:
(3)编写一个Aspectj的实现类并加上注解@Aspect,并在里面使用Aspectj的功能特性。
Spring中 AOP中的两种代理:
代理:简单的理解就是通过为某一个对象创建一个代理对象,我们不直接引用原本的对象,而是由创建的代理对象来控制对原对象的引用
AspectJ采用编译时生成 AOP 代理类,因此具有更好的性能,但需要使用特定的编译器进行处理;而 Spring AOP 则采用运行时生成 AOP 代理类,因此无需使用特定编译器进行处理。由于 Spring AOP 需要在每次运行时生成 AOP 代理,因此性能略差一些AOP的实现关键在于AOP框架自动创建的AOP代理。AOP代理主要分为两大类:
1.静态代理:使用AOP框架提供的命令进行编译,从而在编译阶段就可以生成AOP代理类,因此也称为编译时增强;静态代理一Aspectj为代表,
2.动态代理:在运行时借助于JDK动态代理,CGLIB等在内存中临时生成AOP动态代理类,因此也被称为运行时增强,Spring AOP用的就是动态代理。
1. JDK提供的动态代理技术: JDK的代理方式主要就是通过反射跟动态编译来实现的,主要搭配InvocationHandler和Proxy来实现
2. CGLIB(动态字节码增强技术)
1)JDK动态代理
a. JDK动态代理是面向接口的,必须提供一个委托类和代理类都要实现的接口,只有接口中的方法才能够被代理。
b. JDK动态代理的实现主要使用java.lang.reflect包里的Proxy类和InvocationHandler接口。
原理:
JDK动态代理主要用到java.lang.reflect包中的两个类:Proxy和InvocationHandler。
InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑和业务逻辑编织在一起。
Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
实现动态代理步骤:
A. 创建一个实现接口InvocationHandler的类,他必须实现invoke方法。
B.创建被代理的类以及接口。
C.通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class>[]interfaces, InvocationHandlerhandler)创建一个代理。
D.通过代理调用方法。
2)CGLIB动态代理
CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势植入横切逻辑
原理:运行时动态的生成一个被代理类的子类(通过ASM字节码处理框架实现),子类重写了被代理类中所有非final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势植入横切逻辑。
JDK动态代理和CGLIB字节码生成的区别:
(1)、JDK动态代理只能对实现了接口的类生成代理,而不能针对类。CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法最好不要声明成final。
(2)、JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,它有几个要求
* 实现InvocationHandler;
* 使用Proxy.newProxyInstance产生代理对象;
* 被代理的对象必须要实现接口;
CGLib 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承。
(3)、jdk的核心是实现InvocationHandler接口,使用invoke()方法进行面向切面的处理,调用相应的通知。cglib的核心是实现MethodInterceptor接口,使用intercept()方法进行面向切面的处理,调用相应的通知
Spring事务
1.事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误,本质是数据库对事务的支持
2.Spring并不直接管理事务,而是提供了多种事务管理器,Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器
PlatformTransactionManager 包括(commit、getTransaction、rollback)
1. TransactionStatusgetTransaction(TransactionDefinition definition):根据指定的传播行为,该方法返回当前活动事务或创建一个新的事务。
1.1. TransactionDefinition,是在 Spring 中事务支持的核心接口
int getPropagationBehavior():该方法返回传播行为。Spring 提供了与 EJB CMT 类似的所有的事务传播选项。
int getIsolationLevel():该方法返回该事务独立于其他事务的工作的程度。
String getName():该方法返回该事务的名称。
int getTimeout():该方法返回以秒为单位的时间间隔,事务必须在该时间间隔内完成。
boolean isReadOnly():该方法返回该事务是否是只读的
2.voidcommit(TransactionStatus status):该方法提交给定的事务和关于它的状态。
3.voidrollback(TransactionStatus status):该方法执行一个给定事务的回滚。
事务管理器接口通过getTransaction(TransactionDefinitiondefinition)方法根据指定的传播行为返回当前活动的事务或创建一个新的事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。
在TransactionDefinition接口中定义了它自己的传播行为和隔离级别
1. 实现方式
1.1:编程式:编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理
实现方式:Spring提供两种方式的编程式事务管理,分别是:使用TransactionTemplate和直接使用PlatformTransactionManager。
1.2:声明式:建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务实现方式:根据代理机制的不同,有5种配置方式
1)基于tx和aop名字空间的xml配置文件
2)全注解,@Transactional:最为常用,只需要在配置文件中开启对注解事务管理的支持,然后在需要事务管理的地方加上@Transactional注解
2. 实现原理
配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional标识。
spring 在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。
真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
3. 事务隔离级别(4个)
1. 隔离级别(isolationlevel)。隔离级别定义了一个事务可能受其他并发事务影响的程度
2. 数据库事务(ACID特点、隔离级别、提交commit、回滚rollback)
1.事务定义:事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功
2.ACID
2.1.原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
2.2.一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态
2.3.隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
2.4.持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中
3. 脏毒、不可重复读、幻读
1. 脏读:个事务读到了另一个事务未提交的数据
2. 不可重复读:一个事务对同一行数据重复读取两次,但是却得到了不同的结果,由于在查询间隔,被另一个事务修改并提交
3. 幻读(虚读):一个事务读取到另外一个事务已经提交的数据(一般执行的事insert操作)
四种隔离级别:低-高
1.Read uncommitted(读未提交):就是一个事务可以读取另一个未提交事务的数据。会出现脏读、不可重复读和幻读问题
2.Read committed(读已提交):就是一个事务要等另一个事务提交后才能读取数据可避免脏读,会出现不可重复读和幻读问题。
3.Repeatable read(可重复读):就是在开始读取数据(事务开启)时,不再允许修改操作, ,可以避免脏读和不可重复读,仍会出现幻读问题
4.serializable(序列化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。
4. 事务传播行为(7个)
七大传播行为(propagation:传播)
事务传播行为(propagationbehavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行
1、 PROPAGATION_REQUIRED(required):如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,
2、 PROPAGATION_SUPPORTS(supports):如果当前存在事务,支持当前事务,如果当前不存在事务,就以非事务执行。‘
3、 PROPAGATION_MANDATORY(mandatory:强制):支持当前事务,如果当前存在事务,就支持该事务,如果当前不存在事务,就抛出异常。
4、 PROPAGATION_REQUIRES_NEW(requires_new):创建新事务,无论当前存不存在事务,都创建新事务。
5、 PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,并挂起任何存在的事务。
6、 PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、 PROPAGATION_NESTED(nested:已确定):如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
Spring单列模式
1.单例模式的好处:
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例在。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回(garbage collection)。
2.Spring依赖注入Bean实例默认是单例的。
Spring单例是指一个Spring Bean容器(ApplicationContext)中仅有一个实例。
Spring对bean实例的创建是采用单例注册表的方式进行实现的,而这个注册表的缓存是HashMap对象,如果配置文件中的配置信息不要求使用单例,Spring会采用新建实例的方式返回对象实例
项目加载的时候bean(一个bean对应某个类)自动创建(初始化,建一个实例),而后是每次调用bean的时候是注入的(不是重新new。。所有整个系统都是这个实例,,而且是spring自动提供的)
对于Spring中实现Singleton模式,是以IOC容器为单位(就是说在这个容器里面bean实现Singleton),换句话说,一个JVM可能有多个IOC容器,而在这个容器里实现了singleton bean,
实现原理:
1.定义一个final的ConcurrentHashMap对象,从而该域是线程安全的
privatefinal Map
2. 其中获取单例的代码放置在同步块中
Spring其他产品
1.Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置。
Spring Boot的核心思想就是约定大于配置,一切自动完成
2.Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
3.Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架
SpringMVC
1. 运行原理
具体流程解释:
(1) Http请求:客户端请求提交到DispatcherServlet。
(2) 寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
(3) 调用处理器:DispatcherServlet将请求提交到Controller。
(4)(5)调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
(6)(7)处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
(8)Http响应:视图负责将结果显示到客户端。
DispatcherServlet:
是整个Spring MVC的核心。它负责接收HTTP请求组织协调SpringMVC的各个组成部分。其主要工作有以下三项:
(1)截获符合特定格式的URL请求。
(2)初始化DispatcherServlet上下文对应WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
(3)初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。
专用配置文件:springmvc-context.xml
Spring MVC启动过程依据这两个配置大致分为两个过程:
1、ContextLoaderListener初始化,实例化IoC容器,并将此容器实例注册到ServletContext中。
2、DispatcherServlet初始化,建立自己的上下文,也注册到ServletContext中。
MyBatis
简述:
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情:
1.封装JDBC操作
2.利用反射打通Java类与SQL语句之间的相互转换
MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain OldJava Objects,普通的Java对象)映射成数据库中的记录。
2. 实现原理
1. MyBatis应用程序根据XML配置文件创建SqlSessionFactory,
2. SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。
3. SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,
4. 用完之后关闭SqlSession。
简单的说一下MyBatis的一级缓存和二级缓存?
1.一级缓存,其存储作用域为 Session,当Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear
#{}和${}的区别是什么?
1)${}是Properties文件中的变量占位符,${}是字符串替换。,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。Mybatis在处理${}时,就是把${}替换成变量的值。
2)#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值,使用#{}可以有效的防止SQL注入,提高系统安全性。
mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
resultType和resultMap的区别(二者不能同时存在)
1. resultType:返回的结果类型,比如String、int、Map,也可以是对象
2. resultMap描述如何将结果级映射到JAVA对象,对外部resultMap的引用
select * from t_user where ID= 1;
Struts2
1. 工作原理
工作原理
1 .客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 .这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 .接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 .如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 .ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 .ActionProxy创建一个ActionInvocation的实例。
7 .ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 .一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
二 工作流程
1、客户端浏览器发出HTTP请求.
2、根据web.xml配置,该请求被FilterDispatcher接收
3、根据struts.xml配置,找到需要调用的Action类和方法,并通过IoC方式,将值注入给Aciton
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
6、返回HTTP响应到客户端浏览器
拦截器和过滤器的区别
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
struts2有哪些优点?
1)在软件设计上Struts2的应用可以不依赖于Servlet API和struts API。 Struts2的这种设计属于无侵入式设计;
2)拦截器,实现如参数拦截注入等功能;
3)类型转换器,可以把特殊的请求参数转换成需要的类型;
4)多种表现层技术,如:JSP、freeMarker、Velocity等;
5)Struts2的输入校验可以对指定某个方法进行校验;
6)提供了全局范围、包范围和Action范围的国际化资源文件管理实现
Action是如何接受请求参数的?(前台传来的值)
属性驱动和模型驱动
1. Action本身作为model对象,通过成员setter封装(属性驱动 ),主要用于参数较少的封装,如果分层,不利于将数据传递到业务层
2.创建独立model对象,页面通过ognl表达式封装(属性驱动)
3.:使用ModelDriven接口,对请求数据进行封装 (模型驱动 ) ----- 企业开发的主流(模型驱动有很多特性)
SpringMVC和Struts2的区别
一:框架机制
1. spring mvc的入口是servlet(DispatcherServlet),而struts2是filter(StrutsPrepareAndExecuteFilter),这样就导致了二者的机制不同
二.性能方面
1.spring会稍微比struts快。
1.1.spring mvc是基于方法级别的,一个方法对应一个request上下文,是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进
1.2.sturts是基于类,一个Action对应一个request,response上下文,每次发一次请求都会实例一个action,然后调用setter getter方法把request中的数据注入
三、拦截机制
Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。
四、配置方面
spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高,SpringMVC可以认为已经100%零配置。