《传智播客spring黎活明经典》由会员分享,可在线阅读,更多相关《传智播客spring黎活明经典(67页珍藏版)》请在金锄头文库上搜索。
1、高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring企企业开开发讲师:黎活明讲师:黎活明高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring是什么Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发.高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 IOC 控制反转 public class PersonServiceBean private PersonDao personDao = new PersonDaoBea
2、n(); public void save(Person person) personDao.save(person); PersonDaoBean 是在应用内部应用内部创建及维护的。所谓控制反转就是应用本身应用本身不负责不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 依赖注入(Dependency Injection)当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean 类可以改成如下:public class Pe
3、rsonServiceBean private PersonDao personDao ; /通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。 public PersonServiceBean(PersonDao personDao) this.personDao=personDao; public void save(Person person) personDao.save(person); 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。高级软件人才实作培训专家高级软件人才实作培训专家! !北
4、京传智播客教育 为何要使用Spring至少在我看来,在项目中引入spring立即可以带来下面的好处l降低组件之间的耦合度,实现软件各层之间的解耦。 l 可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。l容器提供单例模式支持,开发人员不再需要自己编写实现代码。l容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。l容器提供的众多辅作类,使用这些类能够加快应用的开发,如: JdbcTemplate、 HibernateTemplate。lSpring对于主流的应用框架提供了集成支持,如:
5、集成Hibernate、JPA、Struts等,这样更便于应用的开发。ControllerServiceDAO高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用Spring的好处当使用spring时,我们可以使用容器提供的众多服务高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 如果使用Spring, 我们就不再需要手工控制事务Hibernate的事务操作: public void save()Session session = sessionFactory.getCurrentSession(); session.beginTransactio
6、n();Info info = new Info(传智播客);info.setContent(国内实力最强的java培训机构);session.save(info );session.getTransaction().commit(); JDBC的事务操作: Connection conn = null; try . conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate(update person where name=叶天); mit(); . catch (Excepti
7、on e) conn.rollback(); finallyconn.close();高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 另外,如果使用spring, 我们也不需要处理复杂的事务传播行为public void payment() Bean1.update();/更新金额 Bean2.save();/记录操作日志如果我们不使用Spring,针对下面这两种业务需求,我们该如何做?第1种可能的业务需求:要求Bean1.update()和Bean2.save()在同一个事务中执行。第2种可能的业务需求:要求不管Bean1.update() 的事务是否成功,都需要记录
8、操作日志。public class Bean1 public void update()/注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate(“update account set amount=? where id=?); public class Bean2 public void save()/注意:下面省略了一些代码 Connection conn = null; conn.setAutoCommit(false); Statement.executeUpdate
9、(“insert into Log (content) values (?); 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用Spring,不再需要我们处理复杂的事务传播行为使用Spring,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求1.要求Bean1.update()和Bean2.save()的在同一个事务中执行2.要求不管Bean1.update() 的事务是否成功,都需要记录日志。Transactional(propagation=Propagation.Required)public void payment() Bean1.upda
10、te();/更新金额 Bean2.save();/记录日志 public class Bean1 Transactional(propagation=Propagation.Required) public void update() executeUpdate(“update account set amount=? where id=?); public class Bean2 Transactional(propagation=Propagation.RequiresNew) public void save()executeUpdate(“insert into Log (conten
11、t) values (?); 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 轻量级与重量级概念的划分经常会有同学问到spring属于轻量级框架,还是重量框架?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务.使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能.对于spring容器,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了spring提供的大部分服务
12、,这时应用就属于重量级。目前EJB容器就因为它默认为应用提供了EJB规范中所有的功能,所以它属于重量级。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用Spring需要的jar到下载到下载springspring,然后进行解压缩,在解压目录中找到下面,然后进行解压缩,在解压目录中找到下面jarjar文件,拷贝到类路径下文件,拷贝到类路径下如果使用了切面编程(AOP),还需要下列jar文件和如果使用了JSR-250中的注解,如Resource/PostConstruct/PreDestroy,还需要下列jar文件高级软件人才实作培训专家高级软件人才实作培训专家! !北
13、京传智播客教育 spring的配置文件模版.该配置模版可以从spring的参考手册或spring的例子中得到。配置文件的取名可以任意,文件可以存放在任何目录下,但考虑到通用性,一般放在类路径下。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 编写spring配置文件时,不能出现帮助信息由于spring的schema文件位于网络上,如果机器不能连接到网络,那么在编写配置信息时候就无法出现提示信息,解决方法有两种:1。让机器上网,eclipse会自动从网络上下载schema文件并缓存在硬盘上。2。手动添加schema文件,方法如下:windwos-preferences-m
14、yeclipse-files and editors-xml-xmlcatalog点add,在出现的窗口中的Key Type中选择URI,在location中选File system,然后在spring解压目录的dist/resources目录中选择spring-beans-2.5.xsd,回到设置窗口的时候不要急着关闭窗口,应把窗口中的Key Type改为Schema location,Key改为高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 实例化spring容器实例化Spring容器常用的两种方式:方法一:在类路径下寻找配置文件来实例化容器ApplicationC
15、ontext ctx = new ClassPathXmlApplicationContext(new Stringbeans.xml);方法二:在文件系统路径下寻找配置文件来实例化容器ApplicationContext ctx = new FileSystemXmlApplicationContext(new String“d:beans.xml“);Spring的配置文件可以指定多个,可以通过的配置文件可以指定多个,可以通过String数组传入。数组传入。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 从spring容器中得到bean当spring容器启动后,因为
16、spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:ApplicationContext ctx = new ClassPathXmlApplicationContext(“beans.xml”);OrderService service = (OrderService)ctx.getBean(personService);高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用dom4j读取spring配置文件public class ItcastC
17、lassPathXmlApplicationContext private List beanDefines = new ArrayList(); public ItcastApplicationContext(String filename) init(filename); private void init(String filename) SAXReader saxReader = new SAXReader(); Document document=null; try URL xmlpath = this.getClass().getClassLoader().getResource(
18、filename); document = saxReader.read(xmlpath); Map nsMap = new HashMap(); nsMap.put(ns,http:/www.springframework.org/schema/beans);/加入命名空间 XPath xsub = document.createXPath(/ns:beans/ns:bean);/创建beans/bean查询路径 xsub.setNamespaceURIs(nsMap);/设置命名空间 List beans = xsub.selectNodes(document);/获取文档下所有bean节
19、点 for(Element element: beans) String id = element.attributeValue(id);/获取id属性值 String clazz = element.attributeValue(class); /获取class属性值 BeanDefinition beanDefine = new BeanDefinition(id, clazz); beanDefines.add(beanDefine); catch(Exception e) e.printStackTrace(); 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育
20、三种实例化bean的方式1.使用类构造器实例化2.使用静态工厂方法实例化public class OrderFactory public static OrderServiceBean createOrder()return new OrderServiceBean();3.使用实例工厂方法实例化:public class OrderFactory public OrderServiceBean createOrder()return new OrderServiceBean();高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Bean的作用域.singleton 在每
21、个Spring IoC容器中一个bean定义只有一个对象实例。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如: 如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:.prototype 每次从容器获取bean都是新的对象。 .request .session .global session高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 指定Bean的初始化方法和销毁方法指定Be
22、an的初始化方法和销毁方法高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 注入依赖对象注入依赖对象基本类型对象注入:基本类型对象注入:/构造器注入/属性setter方法注入注入其他注入其他bean:方式一方式一方式二方式二(使用内部使用内部bean,但该但该bean不能被其他不能被其他bean使用使用)高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 集合类型的装配集合类型的装配public class OrderServiceBean private Set sets = new HashSet();private List lists = ne
23、w ArrayList();private Properties properties = new Properties();private Map maps = new HashMap(); ./这里省略属性的这里省略属性的getter和和setter方法方法高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 集合类型的装配集合类型的装配 lihuoming set sss 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 依赖注入依赖注入l使用构造器注入l使用属性setter方法注入l使用Field注入(用于注解方式)注入依赖对象可以采用手工装配或
24、自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。1.手工装配依赖对象2.自动装配依赖对象高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 依赖注入依赖注入-手工装配手工装配依赖对象,在这种方式中又有两种编程方式手工装配依赖对象,在这种方式中又有两种编程方式1. 在xml配置文件中,通过在bean节点下配置,如/构造器注入/属性setter方法注入2. 在java代码中使用Autowired或Resource注解方式进行装配。但我们需要在xml配置文件中配置以下信息: 这个配置隐式注册了多个对注释进行解析处理的处理器:Au
25、towiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor 注: Resource注解在spring安装目录的高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 依赖注入依赖注入-手工装配在在java代码中使用代码中使用Autowired或或Resource注解方式进行装配,这两个注解的区别是:注解方式进行装配,这两个注解的区别是:Autowired
26、 默认按类型装配默认按类型装配,Resource默认按名称装配,当找不到与名称匹配的默认按名称装配,当找不到与名称匹配的bean才会按类才会按类型装配。型装配。 Autowired private PersonDao personDao;/用于字段上 Autowired public void setOrderDao(OrderDao orderDao) /用于属性的setter方法上 this.orderDao = orderDao; Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按
27、名称装配,可以结合Qualifier注解一起使用。如下: Autowired Qualifier(personDaoBean) private PersonDao personDao;Resource注解和Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。名称可以通过Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。 Resource(name=“personDaoBean”) private P
28、ersonDao personDao;/用于字段上注意:如果没有指定注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,属性,并且按照默认的名称仍然找不到依赖对象时, Resource注解会注解会回退到按类型装配。但一旦指定了回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。属性,就只能按名称装配了。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 依赖注入依赖注入-自动装配依赖对象对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:autowire属性取值如下:lbyType:按类型装配,可以根据属性的类型,在容器中寻找跟该类
29、型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。lbyName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。lconstructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。lautodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。高级软件人才实作培训专家高级软件人才实作培训专家
30、! !北京传智播客教育 通过在通过在classpathclasspath自动扫描方式把组件纳入自动扫描方式把组件纳入springspring容器中管理容器中管理前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了Component、Service、Controller、Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用
31、自动扫描机制,我们需要打开以下配置信息: 其中base-package为需要扫描的包(含子包)。Service用于标注业务层组件、 Controller用于标注控制层组件(如struts中的action)、Repository用于标注数据访问组件,即DAO组件。而Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 JDK动态代理public class JDKProxy implements InvocationHandler private Object targetObject;/代理的目标
32、对象public Object createProxyInstance(Object targetObject)this.targetObject = targetObject;/* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器* 第二个参数设置代理类实现的接口* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法*/return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),this.targetObject.getClass().getIn
33、terfaces(), this);public Object invoke(Object proxy, Method method, Object args)throws Throwable return method.invoke(this.targetObject, args);/把方法调用委派给目标对象当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用CGLIB生成代理public class CGLIBProxy implements MethodInterceptor private Obj
34、ect targetObject;/代理的目标对象public Object createProxyInstance(Object targetObject)this.targetObject = targetObject;Enhancer enhancer = new Enhancer();/该类用于生成代理对象enhancer.setSuperclass(this.targetObject.getClass();/设置父类enhancer.setCallback(this);/设置回调用对象为本身return enhancer.create();public Object intercep
35、t(Object proxy, Method method, Object args,MethodProxy methodProxy) throws Throwable return methodProxy.invoke(this.targetObject, args);CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 AOP中的概念Aspect(Aspect(切面切面) ):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.joinpoin
36、t(joinpoint(连接点连接点) ):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)Pointcut(Pointcut(切入点切入点):):所谓切入点是指我们要对那些joinpoint进行拦截的定义.Advice(Advice(通知通知) ):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知Target(Target(目标对象目标对象):):代理的目标对象Weave(Weave(织入织入):):指将asp
37、ects应用到target对象并导致proxy对象创建的过程称为织入.Introduction(Introduction(引入引入):):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用Spring进行面向切面(AOP)编程要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:Spring提供了两种切面声明方式,实际工作中我们可以选用其中一种:l基于XML配置方式声明切面。l基于注解方式声明切面。高级软件人才实作培训专家高级软件人才实作培训专家! !
38、北京传智播客教育 基于注解方式声明切面首先启动对AspectJ注解的支持(蓝色部分): 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 基于注解方式声明切面Aspectpublic class LogPrint Pointcut(execution(* cn.itcast.service.*.*(.)private void anyMethod() /声明一个切入点Before(anyMethod() & args(userName)/定义前置通知public void doAccessCheck(String userName) AfterReturning(poin
39、tcut=anyMethod(),returning=revalue)/定义后置通知public void doReturnCheck(String revalue) AfterThrowing(pointcut=anyMethod(), throwing=ex)/定义例外通知 public void doExceptionAction(Exception ex) After(anyMethod()/定义最终通知public void doReleaseAction() Around(anyMethod()/环绕通知public Object doBasicProfiling(Proceedi
40、ngJoinPoint pjp) throws Throwable return pjp.proceed();高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 基于基于XML配置方式声明切面public class LogPrint public void doAccessCheck() 定义前置通知public void doReturnCheck() 定义后置通知 public void doExceptionAction() 定义例外通知public void doReleaseAction() 定义最终通知public Object doBasicProfilin
41、g(ProceedingJoinPoint pjp) throws Throwable return pjp.proceed();环绕通知高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 基于基于XML配置方式声明切面 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring+JDBC组合开发 使用Spring+JDBC集成步骤如下:l配置数据源,如: .略 l配置事务。配置事务时,需要在xml配置文件中引入用于声明事务的tx命名空间(见下页),事务的配置方式有两种:注解方式和基于XML配置方式。高级软件人才实作培训专家高级软件人才实作培训专家
42、! !北京传智播客教育 在spring配置文件中引入用于声明事务的tx命名空间高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 配置数据源 使用属性占位符高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用属性占位符方式配置数据源 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 采用注解方式配置事务l采用注解方式采用注解方式 Service TransactionalTransactionalpublic class PersonServiceBean implements PersonService 高级软件人才实作培训专
43、家高级软件人才实作培训专家! !北京传智播客教育 采用基于基于XMLXML方式配置事务 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用JdbcTemplate进行insert/update/delete操作Service Transactionalpublic class PersonServiceBean implements PersonService private JdbcTemplate jdbcTemplate;Resourcepublic void setDataSource(DataSource dataSource) this.jdbcTempl
44、ate = new JdbcTemplate(dataSource); /添加public void save(Person person) throws ExceptionjdbcTemplate.update(insert into person (name) values(?), new Objectperson.getName(), new intjava.sql.Types.VARCHAR);高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用JdbcTemplate获取一条记录Service Transactionalpublic class PersonS
45、erviceBean implements PersonService private JdbcTemplate jdbcTemplate;Resourcepublic void setDataSource(DataSource dataSource) this.jdbcTemplate = new JdbcTemplate(dataSource); public Person getPerson(Integer id)RowMapper rowMapper = new RowMapper()public Object mapRow(ResultSet rs, int rowNum) thro
46、ws SQLException Person person = new Person();person.setId(rs.getInt(id);person.setName(rs.getString(name);return person;return (Person)jdbcTemplate.queryForObject(select * from person where id=?, new Objectid, new intjava.sql.Types.INTEGER, rowMapper);高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 使用JdbcTempla
47、te获取多条记录Service Transactionalpublic class PersonServiceBean implements PersonService private JdbcTemplate jdbcTemplate;Resourcepublic void setDataSource(DataSource dataSource) this.jdbcTemplate = new JdbcTemplate(dataSource);public List getPersons()RowMapper rowMapper = new RowMapper()public Object
48、mapRow(ResultSet rs, int rowNum) throws SQLException Person person = new Person();person.setId(rs.getInt(id);person.setName(rs.getString(name);return person;return jdbcTemplate.query(select * from person, rowMapper);高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 事务传播属性REQUIREDREQUIRED:业务方法需要在一个事务中运行。如果方法运行时,已经
49、处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。NOT_SUPPORTEDNOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。REQUIRESNEWREQUIRESNEW:属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。MANDATORYMANDATORY:该属性指定业务方法只能在一个已经存在的事务中执行,业务方
50、法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出例外。SUPPORTSSUPPORTS:这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。NeverNever:指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。NESTEDNESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保存点。内部事务
51、的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Connection conn = null;try conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate(update person set name=888 where id=1); Savepoint savepoint = conn.setSavepoint(); try conn.creat
52、eStatement().executeUpdate(update person set name=222 where sid=2); catch(Exception ex) conn.rollback(savepoint); stmt.executeUpdate(delete from person where id=9); mit(); stmt.close(); catch (Exception e) conn.rollback(); finally try if(null!=conn & !conn.isClosed() conn.close(); catch (SQLExceptio
53、n e) e.printStackTrace(); 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 数据库系统提供了四种事务隔离级数据库系统提供了四种事务隔离级别供用户选择。不同的隔离级别采用不同的锁类型来实现,在四种隔离级别中,Serializable的隔离级别最高,Read Uncommited的隔离级别最低。大多数据库默认的隔离级别为Read Commited,如SqlServer,当然也有少部分数据库默认的隔离级别为Repeatable Read ,如MysqllRead Uncommited:读未提交数据(会出现脏读,不可重复读和幻读)。lRead Commi
54、ted:读已提交数据(会出现不可重复读和幻读)lRepeatable Read:可重复读(会出现幻读)lSerializable:串行化脏读脏读:一个事务读取到另一事务未提交的更新新据。不可重复读:不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一事务已提交的更新数据。幻读:幻读:一个事务读取到另一事务已提交的insert数据。高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发hibernate核心安装
55、包下的核心安装包下的:librequired*.jarhibernate 注解安装包下的注解安装包下的Spring安装包下的安装包下的、Struts下载struts-1.3.8-lib.zip,需要使用到解压目录下的所有jar,建议把和更换为版本。Spring中已经存在一个,所以把struts中的删除,避免jar冲突。数据库驱动数据库驱动jar高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发 . 略 cn/itcast/bean/Person.hbm.xml hibernate.hbm2ddl.auto=update hibernate.show_sql=fal
56、se hibernate.format_sql=false 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发实体bean配置模版 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发Hibernate二级缓存的配置 cn/itcast/bean/Person.hbm.xml hibernate.hbm2ddl.auto=update hibernate.show_sql=false hibernate.format_sql=false hibernate.cache.use_second_level_cache=true hibern
57、ate.cache.use_query_cache=false 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发在需要缓存的实体bean配置文件中加入缓存配置项 usage说明了缓存的策略,region指定缓存的区域名高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发Ehcache默认的配置文件ehcache.xml(放在类路径下) defaultCache节点为缺省的缓存策略 maxElementsInMemory 内存中最大允许存在的对象数量 eternal 设置缓存中的对象是否永远不过期 overflowToDisk 把溢出的
58、对象存放到硬盘上 timeToIdleSeconds 指定缓存对象空闲多长时间就过期,过期的对象会被清除掉 timeToLiveSeconds 指定缓存对象总的存活时间 diskPersistent 当jvm结束是是否持久化对象 diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发在web容器中实例化spring容器, contextConfigLocation classpath:beans.xml org.springframework.web.conte
59、xt.ContextLoaderListener高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发在web容器中配置struts,strutsorg.apache.struts.action.ActionServletconfig/WEB-INF/struts-config.xml0struts*.do高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发如果action没有交给spring管理时,我们通过下面语句获取spring容器实例WebApplicationContext ctx = WebApplicationContextUt
60、ils.getWebApplicationContext(this.getServlet().getServletContext();把action交给spring管理后,我们可以使用依赖注入在action中注入业务层的bean。确保action的path属性值与bean的名称相同。Spring 配置:在struts配置文件中添加进spring的请求控制器,该请法语控制器会先根据action的path属性值到spring容器中寻找跟该属性值同名的bean。如果寻找到即使用该bean处理用户请求 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发org.spring
61、framework.web.struts.DelegatingRequestProcessor 的处理过程。假设用户请求的路径为:/person/list.doActionServletDelegatingRequestProcessor请求处理器Spring容器Action交给了容器管理bean name=“/person/list”class=“cn. PersonAction” 获取action对象高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发使用spring解决乱码问题。encodingencodingUTF-8encoding/*高级软件人才实作培训
62、专家高级软件人才实作培训专家! !北京传智播客教育 整合开发使用spring解决hibernate因session关闭导致的延迟加载例外问题。 OpenSessionInViewFilter OpenSessionInViewFilter /*高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发这里JPA的实现采用hibernate,需要使用到下面的jar文件Hiberante核心包(8个文件)-librequired*.jarHiberante注解包注解包(3个文件个文件-、Hibernate针对针对JPA的实现包的实现包(3个文件个文件-、高级软件人才实作培训专
63、家高级软件人才实作培训专家! !北京传智播客教育 整合开发JPA规范要求在类路径的META-INF目录下放置,文件的名称是固定的,配置模版如下: 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发在spring中配置EntityManagerFactory 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 整合开发使用spring解决JPA因EntityManager关闭导致的延迟加载例外问题。 Spring OpenEntityManagerInViewFilter Spring OpenEntityManagerInViewFilter
64、/* 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring2.5+Hibernate3.3+Struts2整合开发使用到struts2的lib目录下所有不带-plugin结尾的jar文件,但除了 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring2.5+Hibernate3.3+Struts2整合开发在web容器中实例化spring容器和配置struts2 contextConfigLocation classpath:beans.xml org.springframework.web.context.ContextLoader
65、Listener配置配置struts2 struts2 org.apache.struts2.dispatcher.FilterDispatcher struts2 /* 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring2.5+Hibernate3.3+Struts2整合开发struts2的配置文件模版 /WEB-INF/page/message.jsp /WEB-INF/page/persons.jsp/WEB-INF/page/add_person.jsp/WEB-INF/page/edit_person.jsp 高级软件人才实作培训专家高级软件人才实作培训专家! !北京传智播客教育 Spring2.5+Hibernate3.3+Struts2整合开发struts2的标签姓名:, a href=修改