Sprig核心概念
Spring致力于havaEE应用的各种解决方案,而不是仅仅专注于某一层的方案。可以说,Spring是企业应用开发的“一站式”选择,Spring贯穿表现层,业务层,持久层。
Spring体系结构:
Spring 有可能成为所有企业应用程序的一站式服务点,然而,Spring 是模块化的,允许你挑选和选择适用于你的模块,不必要把剩余部分也引入。下面的部分对在 Spring 框架中所有可用的模块给出了详细的介绍。
Spring 框架提供约 20 个模块,可以根据应用程序的要求来使用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSUml0Td-1570667190198)(C:\Users\陈陈\Desktop\Y2zy\图片\arch1.png)]
Spring Ioc
控制反转:指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,是面向对象编程中的一种设计理念,用来降低代码之间的耦合度。
Spring Aop
面向切面编程:是软件编程思想发展到一定阶段的产物,是对面向编程的有益补充。Aop一遍适用具有横切逻辑的场合
面向切面基本概念:
-
面向切面编程,AOP(Aspect Oriented Programming),要解决的问题是将横切关注点与业务逻辑分离
-
横切关注点:在软件开发中,散布于应用多处的功能。
-
通知:定义了切面是什么,何时使用切面。分为:前置通知,后置通知,返回通知,异常通知,环绕通知
-
连接点:在应用程序执行过程中能够插入切面的一个点,该点可以是调用方法时、抛出异常时、甚至是修改一个字段时。切面代码可以利用这些切点插入到应用的正常流程中,并添加新的行为。
-
切点:定义了切面的“何处”。有助于缩小切面所通知的连接点的范围,切点的定义会匹配通知要织入的一个或多个连接点。
-
切面:通知与切点的结合。
-
引入:允许向现有的类添加新方法或属性
-
织入:把切面应用到目标对象并创建新的代理对象的过程。
使用Spring Aop实现日志输出
1.在项目中添加Spring Aop相关的jar文件
2.编写前置增强和后置增强实现日志功能
3.编写Spring配置文件,对业务方法进行增强处理
4.编写代码,获取带有增强处理的业务对象
Ioc 和Aop使用扩展
使用p命名空间实现注入属性注入:
给XML配置文件"减肥"的另一个选择就是使用p名称空间,从 2.0开始,Spring支持使用名称空间的可扩展配置格式。这些名称空间都是基于一种XML Schema定义。事实上,我们所看到的所有bean的配置格式都是基于一个 XML Schema文档。
特定的名称空间并不需要定义在一个XSD文件中,它只在Spring内核中存在。我们所说的p名称空间就是这样,它不需要一个schema定义,与我们前面采用元素定义bean的属性不同的是,当我们采用了p名称空间,我们就可以在bean元素中使用属性(attribute)来描述bean的property值。
下面的两段XML配置文件中都是用来定义同一个bean:一个采用的是标准的XML格式,一个是采用p名称空间。
<bean name="classic" class="com.example.ExampleBean">
<property name="email" value="foo@bar.com/>
</bean>
<bean name="p-namespace" class="com.example.ExampleBean"
p:email="foo@bar.com"/>
注入不同数据类型
1.注入直接量(数据类型,字符串)
2.引用其他bean组件
3.使用内部bean
4.注入集合类型的属性
5.注入null可空字符串
其他增强类型
异常抛出增强
1.首先人为制造一个异常,
1 package com.dao.impl;
2
3 import com.dao.IUserDao;
4 import com.domain.User;
5
6 public class IUserDaoImpl implements IUserDao {
7
8 @Override
9 public void save(User user) {
10 // TODO Auto-generated method stub
11 System.out.println("哇塞,保存用户信息了");
12 //故意制造异常
13 throw new RuntimeException("看到这个别紧张,是故意制造的异常");
14 }
15
16 }
2.写个异常处理类
1 package com.aop;
2
3 import java.sql.SQLException;
4 import java.lang.reflect.Method;
5 import org.apache.log4j.Logger;
6 import org.springframework.aop.ThrowsAdvice;
7
8 public class ErrorLogger implements ThrowsAdvice {
9
10 private static final Logger log = Logger.getLogger(ErrorLogger.class);
11
12 public void afterThrowing(Method method,Object[] args, Object target, RuntimeException e){
13 log.error(method.getName()+"方法发生异常:"+e);
14 }
15 public void afterThrowing(Method method,Object[] args, Object target, SQLException ex){
16 log.error(method.getName()+"方法发生异常:"+ex);
17 }
18 }
3.配置spring配置文件,记得到aop空间
1 <bean id="dao" class="com.dao.impl.IUserDaoImpl"></bean>
2 <bean id="biz" class="com.biz.impl.IUserBizImpl">
3 <property name="dao" ref="dao"></property>
4 </bean>
5 <bean id="errorlog" class="com.aop.ErrorLogger"></bean>
6 <aop:config>
7 <!-- <aop:pointcut expression="execution(public void save(com.domain.User))" id="pointcut"/>-->
8 <aop:pointcut expression="execution(* com.biz.IUserBiz.*(..))" id="pointcut"/>
9 <aop:advisor advice-ref="errorlog" pointcut-ref="pointcut"/>
10 </aop:config>
4.编写测试类
1 package com.test;
2
3 import org.springframework.context.ApplicationContext;
4 import org.springframework.context.support.ClassPathXmlApplicationContext;
5 import com.biz.IUserBiz;
6 import com.domain.User;
7
8 /**
9 *
10 * @author Mr
11 * aop测试类
12 */
13 public class Test {
14
15 public static void main(String[] args) {
16 //解析配置文件
17 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
18
19 IUserBiz biz = (IUserBiz) ac.getBean("biz");
20 User user = new User();
21 user.setUname("小老虎");
22 biz.save(user);
23 }
24
25 }
5.测试效果
最终增强
定义最终增强
@AspectJ还提供了一种最终增强类型,无论方法抛出异常还是正常退出,该增强都会得到执行,类似于异常处理机制中的finally块的作用,一般用于释放资源。
环绕增强
环绕增强在目标方法的前后都可以织入增强处理,环绕增强是功能最强大的增强处理,spring把目标方法的控制权全部交给了它,在环绕增强处理中,可以获取或修改目标方法的参数、返回值、,可以对它进行异常处理,其次可以决定目标方法是否执行。
1.AroundLogger类
1 package com.aop;
2
3 import java.lang.reflect.Method;
4 import java.util.Arrays;
5
6 import org.aopalliance.intercept.MethodInterceptor;
7 import org.aopalliance.intercept.MethodInvocation;
8 import org.apache.log4j.Logger;
9 /**
10 *
11 * @author Mr
12 * 环绕增强处理
13 */
14 public class AroundLogger implements MethodInterceptor {
15
16 private static final Logger log = Logger.getLogger(AroundLogger.class);
17
18 @Override
19 public Object invoke(MethodInvocation arg0) throws Throwable {
20 //处理代理对象
21 Object obj = arg0.getThis();
22 //获取代理方法
23 Method method =arg0.getMethod();
24 //获取方法参数
25 Object [] args = arg0.getArguments();
26 log.info("调用"+obj+"的"+method.getName()+"方法,方法参数是:"
27 +Arrays.toString(args));
28 try {
29 Object result = arg0.proceed();//调用目标方法,获取目标方法的返回值
30 log.info("调用"+obj+"的"+method.getName()+"方法,方法返回值是:"
31 +result);
32 return result;
33 } catch (Exception e) {
34 log.error(method.getName()+"方法抛出异常"+e);
35 e.printStackTrace();
36 }
37
38
39 return null;
40 }
41
42 }
2.spring配置文件,记得把IUserDaoImpl.java中的自定义异常删掉
1 <bean id="dao" class="com.dao.impl.IUserDaoImpl"></bean>
2 <bean id="biz" class="com.biz.impl.IUserBizImpl">
3 <property name="dao" ref="dao"></property>
4 </bean>
5 <bean id="aroundlog" class="com.aop.AroundLogger"></bean>
6 <aop:config>
7 <!-- <aop:pointcut expression="execution(public void save(com.domain.User))" id="pointcut"/>-->
8 <aop:pointcut expression="execution(* com.biz.IUserBiz.*(..))" id="pointcut"/>
9 <aop:advisor advice-ref="aroundlog" pointcut-ref="pointcut"/>
10 </aop:config>
3.测试类
1 package com.test;
2
3 import org.springframework.context.ApplicationContext;
4 import org.springframework.context.support.ClassPathXmlApplicationContext;
5 import com.biz.IUserBiz;
6 import com.domain.User;
7
8 /**
9 *
10 * @author Mr
11 * aop测试类
12 */
13 public class Test {
14
15 public static void main(String[] args) {
16 //解析配置文件
17 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
18
19 IUserBiz biz = (IUserBiz) ac.getBean("biz");
20 User user = new User();
21 user.setUname("小老虎");
22 biz.save(user);
23 }
24
25 }
4.测试效果
使用注解实现Ioc的配置
使用注解定义bean
1.组件注解
@controller 控制器(注入服务)
@service 服务(注入dao)
@repository dao(实现dao访问)
@component (泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。)
其实在Annotation设计之初,是定义了四个组件注解的,每个组件注解声明该组件的功能,但是由于某种原因,这些设计
思想并未真正实现,以至于上面的四个组件注解都是一样的,没有任何区别;
所以当你搞不清当前要注解的类到底是dao层,service层,还是controller层时,建议使用@component注解;
或者说所有组件类都用@component注解,不然,万一dao层类你用了@service注解,虽然代码能够正常运行,但是明眼
人一看就知道你不专业,连dao层和service层都搞不清。
2.Autowired注解
采用@Autowired注解的成员变量、setter方法、构造方法(对应依赖注入的接口注入、setter注入、构造器注入),会让
Spring去做一件事:去所有@component注解的类里面找和我类型相同的,并装配到bean中,它默认是byType的,所以
如果你为多个与之类型相同的类注解了@component,那么Spring就说:我找到了好多和你类型相同的,这下该怎么办啊。
然后华丽丽地报错了。
所以我们建议在使用组件注解时给它起个名字,方式为@component(“eco”),如果不自定义的话,Spring默认为组件起个
名字,这个名字就是该组件类名首字母小写。
那么在@Autowired(name=“eco”),这样显式地声明注入的组件名称为eco,就不会出错了,但是你别故意注入一个类型不
匹配的,那就没意思了。
3.Resource注解
@Resource是一个比@Autowired注解功能更强大的注解,并且更易于理解;
@Autowired(name=“eco”)========@Resource(name=“eco”),这两种注解功能是一样的,都能实现往此处注入一个名为
eco的类(资源)。
如此一来,就可以实现几个注解来实现xml文件手动装配bean的的功能了。
使用注解实现bean组件装配
在这里我们要详细说明一下利用Annotation-注解来装配Bean。
因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看Annotation的魅力所在吧。
先来看看之前的bean注解装配例子:
package com.eco.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.eco.dao.UserDao;
import com.eco.model.User;
@Service
public class Userservice {
//@Autowired
private UserDao userdao;
public void setUserdao(UserDao userdao) {
this.userdao = userdao;
}
public void useradd(User newuser) {
userdao.adduser(newuser);
}
}
package com.eco.daoimp;
import org.hibernate.Session;
import org.hibernate.Transaction;import org.springframework.stereotype.Repository;
import com.eco.hibernate.HibernateSessionFactory;
import com.eco.dao.UserDao;
import com.eco.model.User;
@Repository
public class Usertodo1 implements UserDao {
public void adduser(User user) {
Session session = HibernateSessionFactory.getSession();
Transaction transaction = session.beginTransaction();
session.save(user);
transaction.commit();
session.close();
System.out.println("todo1 create the user");
}
}
使用注解定义切面
Aspectj:是一个面向切面的框架,它扩展了java语言,定义了Aop语法,能够在编译期间提供代码的织入,
(也就是AOP)的动机是发现那些使用传统的编程方法无法很好处理的问题。考虑一个要在某些应用中实施安全策略的问题。安全性是贯穿于系统所有模块间的问题,每个模块都需要应用安全机制才能保证整个系统的安全性,很明显这里的安全策略的实施问题就是一个横切关注点,使用传统的编程解决此问题非常的困难而且容易产生差错,这就正是AOP发挥作用的时候了。@AspectJ 使用了Java5 的注解,可以将切面声明为普通的Java类。
MyBatis与Spring的整合
spring对MyBatis的整合思路:具体来说,业务逻辑对象依赖基于MyBatis技术实现DAO对象,核心是获取Sqlession是咧,
Spring整合MyBatis的准备工作
1.在项目中加入Spring,MyBatis及整合相关的JAR文件
2.建立开发目录,创建实体类
3.创建数据访问接口
4.4配置SQL映射文件
5.配置MyBatis配置文件
实现Spring对MyBatis的整合
Spring需要依次完成加载MyBatis配置信息,构建SqSessionFactory和SqlSession实列
配置SqlSeeionFactoryBean
Spring-Mybatis — 配置SqlSessionFactoryBean,整合Spring-Mybatis
要利用Mybatis首先是需要导入mybatis-x.x.x.jar,其次,要整合Spring和Mybatis需要导入mybatis-spring-x.x.x.jar。
JAR : mybatis-x.x.x
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.6</version>
</dependency>
JAR : mybatis-spring-x.x.x
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
1、Spring整合Mybatis的xml配置
xml : POM
<!-- DB -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.54</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>7.0.23</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.6</version>
</dependency>
xml : DataSource
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="poolProperties">
<bean class="org.apache.tomcat.jdbc.pool.PoolProperties">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<!-- Register the pool with JMX. In order for the connection pool object to create the MBean. -->
<property name="jmxEnabled" value="true" />
<!-- The indication of whether objects will be validated by the idle object evictor. -->
<property name="testWhileIdle" value="true" />
<!-- The indication of whether objects will be validated before being borrowed from the pool. -->
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="initialSize" value="${jdbc.initialPoolSize}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="maxWait" value="${jdbc.maxWait}" />
<property name="minIdle" value="${jdbc.minIdle}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="maxAge" value="60000" />
<!-- The number of milliseconds to sleep between runs of the idle connection validation/cleaner thread. -->
<property name="timeBetweenEvictionRunsMillis" value="15000" />
<!-- The minimum amount of time an object may sit idle in the pool before it is eligible for eviction. -->
<property name="minEvictableIdleTimeMillis" value="60000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="30" />
<property name="validationQuery" value="SELECT 1" />
<property name="validationInterval" value="30000" />
</bean>
</property>
</bean>
使用SqSessionTemplate实现数据库的操作
EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bdqn.dao.EmployeeMapper">
<select id="getEmployeeList" resultType="Employee">
select * from Employee
</select>
<insert id="addEmployee" parameterType="Employee">
insert into employee (sn,name,gender) values (#{sn},#{name},#{gender})
</insert>
<update id="modifyEmployee" parameterType="Employee">
update employee
<set>
<if test="sn != null"> sn = #{sn},</if>
<if test="name != null"> name = #{name},</if>
<if test="gender != null"> gender = #{gender}</if>
</set>
where id = #{id}
</update>
<delete id="deleteEmployee" parameterType="Employee">
delete from employee where id = #{id}
</delete>
</mapper>
Employee.java
public class Employee {
private Integer id;
private String sn;
private String name;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
测试类
public class EmployeeDaoTest {
private SqlSessionTemplate sqlSessionTemplate;
protected ApplicationContext ctx = null;
private EmployeeDaoTest test;
private Logger logger = Logger.getLogger(EmployeeDaoTest.class);
@Before
public void setUp() throws Exception{
ctx = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
test = (EmployeeDaoTest)ctx.getBean("employeeDaoTest");
}
@Test
public void getEmployeeListTest() {
List<Employee> list = test.sqlSessionTemplate.selectList("cn.bdqn.dao.EmployeeMapper.getEmployeeList");
logger.debug("testGetEmployeeList---> " + list.size());
}
@Test
public void addEmployeeTest(){
Employee employee = new Employee();
employee.setSn("CESHI");
employee.setName("测试");
employee.setGender("男");
int flag = test.sqlSessionTemplate.insert("cn.bdqn.dao.EmployeeMapper.addEmployee", employee);
Assert.assertEquals(1, flag);
}
@Test
public void modifyEmployeeTest(){
Employee employee = new Employee();
employee.setId(8);
employee.setSn("CESHI888");
employee.setName("测试888");
employee.setGender("男");
int flag = test.sqlSessionTemplate.update("cn.bdqn.dao.EmployeeMapper.modifyEmployee", employee);
Assert.assertEquals(1, flag);
}
@Test
public void deleteEmployeeTest(){
Employee employee = new Employee();
employee.setId(8);
int flag = test.sqlSessionTemplate.delete("cn.bdqn.dao.EmployeeMapper.deleteEmployee", employee);
Assert.assertEquals(1, flag);
}
public SqlSessionTemplate getSqlSessionTemplate() {
return sqlSessionTemplate;
}
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
}
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<!--这里给实体类取别名,方便在mapper配置文件中使用-->
<package name="cn.bdqn.pojo"/>
</typeAliases>
</configuration>
applicationContext-mybatis.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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Properties文件读取配置,base的properties -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- JNDI获取数据源(使用dbcp连接池) -->
<!-- 因为我们使用的这个数据源是采用 dbcp连接池,对于连接池来说,整个应用中只有一个,
所以作用域需要设置成单例 因为获取数据源是非常消耗性能,所以我们也要采用单例模式-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
scope="singleton">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
<!-- 事务配置 在需要事务管理的地方加@Transactional 注解或者AOP进行事务处理-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置mybitas SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="mapperLocations" value="classpath:cn/bdqn/dao/*.xml"/>
</bean>
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<!-- spring使用构造的方法进行注入 -->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 把sqlSessionTemplate注入测试类 -->
<bean id="employeeDaoTest" class="cn.bdqn.test.EmployeeDaoTest">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
</beans>
为业务添加声明事务
propagation:事务机制,
一、在声明式的事务处理中,要配置一个切面,其中就用到了propagation,表示打算对这些方法怎么使用事务,是用还是不用,其中propagation有七种配置,REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。默认是REQUIRED。
二、Spring中七种Propagation类的事务属性详解:
REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。
三、注意.
这个配置将影响数据存储,必须根据情况选择
isolation:事务隔离等级
隔离级别 | 含义 |
---|---|
ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别。 |
ISOLATION_READ_UNCOMMITTED | 允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。 |
ISOLATION_READ_COMMITTED | 允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。 |
ISOLATION_REPEATABLE_READ | 对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。 |
ISOLATION_SERIALIZABLE | 完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。 |
SpringMVC体系结构和处理请求控制器
MVC设计模式:
数据访问层:DAO层
处理业务逻辑:SErvice层
数据实体:pojo
负责前段请求的接受并处理:Servlet
负责前端页面展示:JSP
jsp Mode1
一:Model1
1、模型:主要还是通过JSP页面和业务逻辑处理。
2、时序图:
jsp Mode2
1、模型
2、时序图
三、区别
1、Model1适合小型项目开发,结构简单,开发迅速。但是JSP页面相对复杂,不利于维护。
2、Model1适合大型项目开发,职责明确,而且适应变动的需求。
3、从模型上和时序图上很容易看出,Model2是在Model1的基础上,分离了控制,将业务逻辑处理分离出来。这样Model2相对来说便于维护。
1.mvc三部分(模型,视图,控制层)
2.mvc优缺点
1、可以为一个模型在运行时同时建立和使用多个视图。变化-传播机制可以确保所有相关的视图及时得到模型数据变化,从而使所有关联的视图和控制器做到行为同步。
2、视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换。
3、模型的可移植性。因为模型是独立于视图的,所以可以把一个模型独立地移植到新的平台工作。需要做的只是在新平台上对视图和控制器进行新的修改。
4、潜在的框架结构。可以基于此模型建立应用程序框架,不仅仅是用在设计界面的设计中。
MVC的不足之处
1、增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
2、视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
3、视图对模型数据的低效率访问。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
4、目前,一般高级的界面工具或构造器不支持模式。改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成MVC使用的困难。
Spring MVC介绍及其环境搭建
Controller替换Servlet来担负控制器的职责,COntroller接收请求,调用相应的MOdel进行处理
Spring MVC环境搭建
1.引入JAr文件
2.Spring MVC配置
3.创建Controller
4.创建View
5部署运行
Spring MVC 框架的请求处理流程及体系结构
(1)首先用户发送请求到前端控制器(DispatcherServlet),前端控制器根据请求信息(如URL)来决定选择哪个页面控制器(Controller)来进行处理,并把请求委托给它,即Servlet控制器的控制逻辑部分。
(2)页面控制器接收到到请求后,进行业务处理,处理完毕后返回一个ModelAndView(模型数据和逻辑视图名)。
(3)前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的真正视图,并把模型数据传入以便将视图渲染展示。
(4)前端控制器再次收回控制权,将响应结果返回给用户,至此整个流程结束。
Spring MVC通过一个前端控制器(DispatcherServlet)接收所有的请求,并将具体工作委托给其他组件进行处理,DispatcherServlet处于核心地位,它负责协调组织不同组件完成请求处理并返回响应。每个组件所负责的工作内容?
(1)客户端发出HTTP请求,Web应用服务器接受此请求。若匹配DispatcherServlet的请求映射路径(在web.xml中指定),则Web容器将该请求转交给DispatcherServlet处理。
(2)DispatcherServlet接收到该请求后,将根据请求的信息(包括URL、请求参数、HTTP方法等)及HandlerMapping的配置(在-servlet.xml中配置)找到处理请求的处理器(Handler)。
(3)当DispatcherServlet根据HandlerMapping找到对应当前请求的Handler之后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HanlerAdapter可以理解为具体使用Handler来干活的人。
(4)在请求信息到达真正调用Handler的处理方法之前的这段时间内,Spring MVC还完成了很多工作,它会将请求信息以一定方式转换并绑定到请求方法的入参中,对于入参的对象会进行数据转换、数据格式化以及数据校验等。
这些都做完之后,最后才真正地调用Handler的处理方法进行相应的业务逻辑处理。
(5)处理器完成业务逻辑处理之后将返回一个ModelAndView对象给DispatcherServlet,ModelAndView对象包含了逻辑视图名和模型数据信息。
(6)ModelAndView对象中包含的是“逻辑视图名”,而非真正的视图对象。DispatcherServlet会通过ViewResolver将逻辑视图名解析为真正的视图对象View。当然,负责数据展示的视图可以为JSP、XML、PDF、JSON等多种数据格式,
对应Spring MVC均可灵活配置。
(7)当得到真正的视图对象View后,DispatcherServlet会使用ModelAndView对象中的模型数据对View进行视图渲染。
(8)最终客户端获得响应消息,根据配置,可以是普通的HTML页面,也可以是一个XML或者JSON格式的数据等。
3)Spring MVC框架的特点
(1)清晰地角色划分。Spring MVC在Model、View和Controller方面提供了一个非常清晰的角色划分,这三个方面真正是各司其职、各负其责。
(2)灵活的配置功能。以为Spring的核心是IoC,同样在实现MVC上,也可以把各种类当作Bean来通过XML进行配置。
(3)提供了大量的控制器接口和实现类。开发者可以使用Spring提供的控制器实现类,也可以自己实现控制器接口。
(4)真正做到与View层的实现无关(JSP、Velocity、XSLT等)。它不会强制开发者使用JSP,也可以根据项目需求使用Velocity、XSLT等技术,使用起来更加灵活。
(5)国际化支持。
(6)面向接口编程。
(7)Spring提供了Web应用开发的一整套流程,不仅仅是MVC,它们之间可以很方面地结合一起。