java初级ppt笔记

java web 开发技术概述
tomcat:开源servlet容器,java编写

Scanner scan = new Scanner(System.in);//.useDelimiter("\\s")
String str = scan.nextLine();//nextInt
scan.close();
String e = "[\u4e00-\u9fa5]"
for(String s: array_str)
str.matches(e)
String[] a = {"", ""};
ArrayList<Prog1> a = new ArrayList<Prog1>();
toCharArray()
FileWriter fw = new FileWriter("path");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("a" + "\n");
bw.newLine();
rw.readLine();
int[][] a = {}


servlet filter listener
典型的Web应用交互过程: 客户端<-> 服务端<-> 数据库
客户端(前端)技术: html javascript css
服务端(后端)技术:web服务器 javaee 中间件 
Server.xml配置简介


jsp
是一种可以响应客户端请求而动态生成各种格式web网页的技术标准
是以java语言作为脚本语言的,运行在服务端。跨平台。


JSP原理:浏览器<-> servlet容器(jsp javabean) <->数据库


JSP动作指令
forward include forward param plugin useBean setProperty getProperty


JSP内置对象 request page response session application config


Java Servlet
是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
和CGI相比的优势:
性能更好。
在web服务器的地址空间内执行,这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
平台独立,能使用java类库全部功能。


Servlet生命周期
Servlet默认在第一次访问时调用init方法初始化;如果配置了<load-on-startup></load-on-startup>,则在应用启动时加载,并且按load-on-starup指定值由低到高加载。


servlet实现方式
1自定义servlet 可继承,如HttpServlet
2 在web.xml中配置
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>com.MyServlet</servlet-class>
<servlet-mapping>
<servlet-name>..
<url-pattern>..


什么是Filter
能拦截和过滤客户端和服务端的交互数据。
和servlet一样需要在web.xml中配置
<filter>
<filter-name>
<filter-class>
<filter-mapping>


什么是Listener
Listener是可用来监听application、session、request三个对象创建、销毁或者往其中添加、修改、删除属性事件的Java类。当这些事件发生时,响应Listener的方法会被自动调用。
ServletContextListener HttpSessionListener(接口)
同样需要在web.xml中配置,不过要简单一点


Servlet、Filter、Listener对比
初始化顺序:
       整体顺序:Listener > Filter > Servlet; 
       Listener之间按照web.xml声明顺序初始化;
       Filter之间按照web.xml中filter-mapping配置顺序逆序初始化;
       Servlet如果不配置load-on-startup,则不会在应用容器启动时初始化,在第一次访问时才会初始化;Servlet直接按照load-on-startup指定的数字顺序(从小到大)初始化;
初始化影响:
       Listener和Filter初始化失败均会造成ServletContext加载失败,应用无法访问;Servlet初始化失败只会导致针对该Servlet的访问异常。
Mapping配置:
       Listener不配置;Filter可以不配置(不起作用),可以重复配置(按照配置顺序逆序调用);Servlet可以不配置(不起作用),不可以重复配置。


技术展望之SSH/SSM
技术展望之ZA21(云应用开发框架)
技术展望之云平台PaaS


java7新特性
整形数据的二进制表示
可以用八进制、十进制、十六进制来表示一个整形数据(byte, short, int, and long) 。
0 0x 0b 0B
二进制表示是的数据之间的关系能够表现的清晰
下划线分割数值数据
999_999
下滑线并不是可以加在任意位置的,以下位置不可出现下划线:
switch(string)
类型推断增强
List<String> list1 = new ArrayList<>();
public <X> AAA(X x){
}
public static <T> void print(T t){}
try-with-resources
try(文件打开关闭,自动托管,和python类似) 资源释放早,分号隔开 释放顺序,真正异常try
Throwable[] exceptions = e.getSuppressed()
catch多个异常用|隔开
异常类型推断增强
throw new MyException()
throws MyException
throw e




Fork/Join思想、要解决的问题
耗时,拆分 合并,符合多核要求


任务窃取( work-stealing )
双端队列,减少竞争


我们通过继承RecursiveTask,实现其中的compute方法来定义我们的任务,在方法中我们将任务拆分成多个子任务,最终汇集所有子任务的结果返回
compute 返回参数,通过task.get()可以获取
需要一个ForkJoinPool线程池来执行我们的任务,线程池的数量一般为处理器的核数。然后将任务提交给线程池执行,最终等待处理结果。


ForkJoin框架实现原理


ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责存放程序提交给ForkJoinPool的任务,而ForkJoinWorkerThread数组负责执行这些任务。
fork 将任务加入到队列中
join 阻塞当前线程并等待返回结果 do join状态:NORMAL CANCELLED SIGNAL EXCEPTIONAL


java8新特性
Lambda表达式
Arrays.sort(my_list, (o1,o2)->o1.compareToIgnoreCase(o2));
用于创建(实例化)函数式接口对象的一种新语法。函数式接口,指的是只有一个抽象方法的接口。
所以只要实现其抽象方法即可。参数列表->方法实现逻辑
要求:一个参数可无(),多条表达式;return


方法引用
将lambda更加精简化为方法引用。因为方法已经定义了。参数都是默认
方法引用和Lambda表达式的使用场景是一样的,都是用于创建(实例化)函数式接口对象
引用静态方法(类名::静态方法名);
引用特定实例的实例方法(对象::实例方法);
引用特定类的任意实例的实例方法(类名::实例方法);
引用构造方法(类名::new);


personList.sort((p1,p2)->Person.compareByAge(p1,p2)));
personList.sort(Person::compareByAge);
//list的sort方法,要求传入Compare对象


默认方法场景
已经实现的方法。只要在方法前加上default关键字,接口中会默认加上pubic修饰符
实现类中无需实现该方法,可重写。
解决的问题:
在接口中新增方法,能兼容已有实现类功能。


静态方法
接口中可通过静态方法来定义一些通用、固定逻辑,简化应用开发,做到“用户只需关系要做什么,而不需要关系怎么做” 


什么样的接口叫做函数式接口
当一个接口只包含一个抽象方法时,这个接口就是函数式接口。


@FunctionalInterface注解,作用是在定义函数式接口时,让编译器对接口进行检验。如果不满足函数式接口条件时,会给出错误提示信息。


jdk1.8之前的函数式接口有:
java.lang.Runable
java.util.Comparator
java.io.FileFilter

jdk1.8中的函数式接口定义在:
java.util.function中


Stream
是对Collection的增强,专注于聚合操作
借助lambda表达式
同时处理过程。提供串行和并行两种模式进行汇聚操作。高并发
Arrays.asList(nums).stream().
filter(item -> item > 1)
.forEach(System.out::print);
stream是List的默认方法,而filter和forEach是stream的默认方法


流操作类型
Intermediate
可以有多个intermediate操作,是lazy的,并没有开始真正执行
如:filter sorted flatMap map
Terminal
只能有一个Terminal操作,开始真正执行计算。并返回结果
如:forEach reduce min max
short-circuiting
是指无限大返回有限大流,同时在有限时间计算出结果。
如:anyMatch findFist


并行处理流
list.parallelStream().forEach(…)


Optional类
Optional<String> a=…
if(a.isPresent())//不为空


新增日期 时间api
特点:
所有日期接口都是不可变的,是线程安全的
实现类一系列方法用以完成通用任务
新接口介绍:
java.time //LocalDate LocalTime 处理绝大多数要求
java.time.chrono
java.time.format
java.time.temporal //如某月的最后一天
java.time.zone
如:
LocalDate date = LocalDate.now()
LocalDate date = LocalDate.parse(“2017-09-09”)
LocalDate date = LocalDate.of(2017,9,9)
yyyy-MM-dd


LocalTime time = LocalTime.now()
hh:mm:ss.zzz


LocalDateTime  yyyy-MM-dd-HH-mm-ss.zzz
Instant 时间戳


Base64编码
java.util.Base64
getEncoder()
getUrlEncoder()
getMimeEncoder()
encoder.encodeToString(…)


类型推断增强
stringList.addAll(Arrays.asList()) //java8


其它
类型注解:注解可以写在使用类型的任何地方,配合第三方插件工具
Checker Framework,可以在编译的时候检测出runtime error,提高代码质量
重复注解


java开发规范
所有源文件都应该在开头有一个注释,列出类名、版本信息、日期和版权声明
     开头注释
    包和引入语句
    类和接口声明
/**
  * 下面是图像转换的算法实现,彩色图像到灰度图像的转换主要利用
  * RGB色彩空间到YUV色彩空间的变换公式来取得灰度值Y,公式是:
  *   Y = 0.299R + 0.587G +0.114B
  */


进层级。如果一个注释不能在一行内写完,就该采用块注释。
推荐一行一个声明
返回语句, 一个带返回值的return语句不使用小括号“()”,除非它们以
  某种方式使返回值更显见
if语句问题用“{”和“}”括起来
每当一个case顺着往下执行时(因为没有break语句),通常应在break语句的位置添加注释
避免在方法中出现多个return语句(退出点)
不能在finally中返回值
异常捕获后,如果不对该异常进行处理,应该用Log4J记录日志,不要使用标准输出 (如System.out)或 ex.printStackTrace() 
避免使用魔鬼数字(不易理解的数字)
/*
 * @(#)Demo.java        
 *
 * Copyright (c) 1994-2007 CMB  All rights reserved.
 *
 * Copyright infomation
 */


package com.cmb.test;


import java.util.*;


/**
 * Class description goes here.
 *
 * @version 1.82 18 Mar 2016
 * @author    name
 */
public class Demo  {
    /* A class implementation comment can go here. */


  /**
     * ...constructor Blah documentation comment...
     */
    public Demo() {
        // ...implementation goes here...
    }


字符串比较需要使用equals,而不是==,!=,因为==只是对同一引用的对象
比较认为相同,而不比较对象里内容是否相等。
 
    使用StringBuffer代替string+string+string进行字符串相加,n个字符相加,
如果直接用“+“号,会新产生n-1个StringBuffer对象,以及n-1个String对象,
而用StringBuffer只会产生1个String,1个StringBuffer对象。
  
    使用equalsIgnoreCase() 替代 toUpperCase/toLowerCase().equals(),
这样减少一个对象的创建,效率更高。  


    使用StringBuffer.length()替代StringBuffer.toString().length(),这样减少一个对象的创建,效率更高。  


    对于String对象禁止使用string.toString(),本身是String对象,
这样调用效率低下,而且由于string没有判空,很可能导致空异常的风险
字符串比较  
    if(str1.equals(str2)){ 
    statement; 
    } 
  字符串相加 
    StringBuffer strbuf=new StringBuffer(); 
    strbuf.append(str1); 
    strbuf.append(str2); 
    String str=strbuf.toString(); 
  大小写不敏感字符串比较 
    str1. equalsIgnoreCase (str2); 
系统资源释放(谁创建谁释放)


使用clone的规则
由于Collection,Map等类型


属性需要手工进行编程实现。


Clone的规则:  


 Override Clone时,必须执行super.clone();  


 实现Clone方式时,需要抛出CloneNotSurportException; 


所有实现Clone方法的类,必须实现Cloneable接口




懒式方式创建对象:不能采用双检查惯用法
//推荐
public class Foo{ 
  Object baz; 
  Object bar() { 
      synchronized(this){ 
        if(baz == null){ 
          baz = new Object(); 
        } 
      } 
      return baz; 
  } 
}


尽量使用接口而不是具体的类
public java.util.ArrayList getObjectItems(String sql) 


推荐public java.util.List getObjectItems(String sql) 


SOL注入
SQL注入是一种常见攻击方式
SELECT * FROM user_table WHERE username='’or 1 = 1 -- and password='’
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
采用带参方式访问sql语句访问数据库,在java中即采PreparedStatement
的方式访问数据库


并发处理
获取单例对象要线程安全。在单例对象里面做操作也要保证线程安全。
线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁
对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。
创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。
    使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至 countDown方法,直到超时才返回结果。说明:注意,子线程抛出异常堆栈,不能在主线程try-catch到。


异常处理
异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
对大段代码进行try-catch,这是不负责任的表现。 
捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。
     有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务。
     finally块必须对资源对象、流对象进行关闭,有异常也要做try-catch。
     不能在finally块中使用return,finally块中的return返回后方法结束执行,不会再执行try块中的return语句。


遵循30秒法则
如果一个成员函数一个屏幕装不下,那么它就很可能太长了。 




JBOSS中间件开发
by red hed


JBoss企业应用平台架构概览:
全面支持JavaEE6规范。 JCA CDI WebSocket JAXRS
微内核模块化设计。 基于OSGI
多渠道管理。 web cli restful jmx
域管理模式。 多节点管理,批量部署及部署应用
高度可扩展集群。


JBoss MSC。 JBoss 7和WildFfly内核。高并发容器 无多相位设计简单 不依赖JMX核JAVA EE,模块可插拔
DomainController,hostcontroller(单台主机上,帮助管理服务器实例)


jboss eap6:模块可插拔,启动性能提升和内存消耗减少


域管理模式,多节点集中管理
高可扩展应用服务器集群
扩数据中心集群热备。负载均衡(session复制)
一键安装、合规及体检工具AutoOps,一键部署


JBoss  EAP架构部署规范


加入apache。 高可用,灵活,缓存
EAP端口介绍。8080 8443 9990(web) 9999(cli)


EAP环境配置要求。 JAVA_HOME CLASSPATH 加入path
JBoss  EAP目录规范
EAP目录结构介绍


EAP启动脚本规范。
$ /opt/jbshome/appserver/XXXServer1-start-8080.sh    # 启动 JBoss EAP 
$ /opt/jbshome/appserver/XXXServer1-stop-8080.sh    # 停止 JBoss EAP


EWS Tomcat7启动脚本介绍
$ /opt/jbshome/webserver/XXXServer1-start-8080.sh    # 启动 EWS-Tomcat 
$ /opt/jbshome/webserver/XXXServer1-stop-8080.sh    # 停止  EWS-Tomcat 




JBoss EWS配置
在/etc/rc.local 中添加
# EWS httpd 启动示范 
/opt/jbshome/jboss-ews-2.0/httpd/sbin/apachectl   -k  start
# JBoss EAP  XXXServer1 启动示范
su  - qappsom  -c '/opt/jbshome/appserver/XXXServer1-start-8080.sh'
# EWS Tomcat-XXXServer1 启动示范
su   - qappsom  -c '/opt/jbshome/webserver/XXXServer2-start-8180.sh'




JBoss EAP modcluster配置
mod_cluster 是基于httpd的负载均衡项目,能够代理请求给JBoss EAP。
245         <mod-cluster-config advertise-socket="modcluster" proxy-list="http1-IP:80, http2-IP:80" advertise="false" connector="ajp">


JBoss EAP 数据源配置
使用Module方式 发布JDBC驱动程序。
需要做两步: 1.添加Module,2.配置datasources (如下已添加PostgresSql JDBC为例)
JBoss EAP配置文件 /opt/jbshome/appserver/Server1/configuration/standalone-mc.xml)
<datasources>
  <datasource jndi-name="java:jboss/PostgresDS" pool-name="PostgresDS">
    <connection-url>jdbc:postgresql://dbServerIP:port/dbName</connection-url>            <!--数据库IP:端口/数据库名-->
    <driver>postgresql</driver>
    <security>
      <user-name>username</user-name>    <!-- 用户名及密码 -->
      <password>*******</password>


JBoss EAP 数据源配置WEBUI配置
JBoss EAP 应用后台部署
生产应用自动化部署


JBOSS中间件排错
# ps -ef |grep java |grep jboss.node.name
# ps -ef |grep java | grep tomcat
# ps -ef |grep httpd
# netstat -tln


JBoss EAP应用部署检查
JBoss EAP开发环境软件






spring是什么
是java se/ee开源框架,测试驱动,并提供一站式解决方案
spring的组成部分
组成: IOC/DI JDBC/ORM集成(Hibernate) AOP/事物管理 MVC


为什么需要ioc/di
IOC容器的实线思想
被动实例化
被动接受装配
主动变被动
迪米特法则,不知道依赖的具体实现,松散耦合
一般使用:
A a = ApplicationContext.getBean(“a”);
//配置文件
<bean id=“a” class=“AImpl”>
  <property name=“b” ref=“b”/>
<bean id=“b” class=“BImpl”>
id 是该bean在容器中的标识,ioc容器会生成代理类,我们使用的是代理类。
scope:定义生命周期,取值:
singleton(第一次请求初始化,和容器一起存活) prototype(生成新的对象,容器不再负责生命周期的管理),
request(请求结束后,生命周期结束,针对xmlwebapplicationcontext容器和http请求)
session(session信息)
另外:除了xml定义也支持注解的方式定义
扫描bean 加入ioc
本质:
容器创建和装配对象,管理对象生命周期。组件被动实例化,被动接受依赖,被动装配。(工厂+反射+相ml配置文件)




什么是di
 DI:依赖注入(Dependency Injection) :用一个单独的对象(装配器)来
装配对象之间的依赖关系 。
类a      类b(组件)
  ioc容器
优点:看清依赖关系(setter),动态注入依赖关系(运行期间决定),提升可用性(组建重用)


使用IoC/DI容器开发需要改变的思路
应用程序只描述创建对象方式,不直接创建,应用程序代码中不直接进行服务的装配,但要描述哪一个组件需要哪个服务由容器负责将这些装配在一起。oo(hollywood)原则:所有组件都是被动的。




IOC/DI总结
IoC容器功能:实例化和初始化组件,装配组件关系、生命周期管理
ioc是思想,只有具有di功能的才叫ioc容器




JDBC/ORM编程模型缺点
传统jdbc:获取连接 声明sql。。。释放连接
spring jdbc执行步骤:声明sql->处理结果集
优点:简洁,spring事物管理,只做需要做的,一致的非检查异常体系


模版设计模式:将可变和不可变的分离,不够灵活
模版设计模式+回调:将可变和不可变的分离,可变通过回调,不够灵活
public interface JdbcOperations {
    //接口定义行为集
    public Object execute() throws SQLException ;

public abstract class AbstractJdbcOperations implements JdbcOperations {
    @Override
    public final Object execute() throws SQLException {
       Connection conn = DataSourceUtils.getConnection();
        try {
            Object retVal = doInConnection(conn);
            conn.commit();
            return retVal;
        }catch (Exception e) {   conn.rollback(); throw e;}
        finally {                          conn.close(); }
    }
    public abstract Object doInConnection(Connection conn) throws SQLException;
}


jdbc框架优点


jdbc template
预编译语句设值相关
preparedstatementsetter
batchpreparedstatementsetter
自定义功能相关
connection callback
callablestatementcallback
statementcallback
preparedstatementcallback
结果处理集相关
resultsetextractor
rowcallbackhandler


预编译语句及存储过程创建相关
preparedstatementcreator
callablestatementcreator


使用实例:
定义template
sql语句
调用template加载sql,同时可调用回调函数
如:
jdbcTemplate定义
<!-- JDBC -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>


/**
 * 查询出删除主表数据相关联的子表数据的数量
 * @param subTableName 子表名称
 * @param fkeyValue 外键值
 * @param fkeyColName 外键字段名
 * @return 子表中与主表中要删除的数据管理的数据的数量
 */
public int getCountSubTabDataByFkey(String subTableName,String fkeyValue,String fkeyColName){


 String sql = "select count(*)   from " + subTableName +
 " where " + fkeyColName + " ='" + fkeyValue + "' ";


 return jdbcTemplate.queryForInt(sql);
}


Spring集成的其他ORM框架
Hibernate JPA JDO Mybatis


Spring Hibernate整合使用示例




AOP事务管理
传统方案的问题:日志记录/性能监控/安全监测。监控代码与业务逻辑紧密耦合,需求变动会带来噩梦
改进方案:装饰器与代理模式
aop的解决方案:
@Aspect
public class PayEbiAspect {    
    @Pointcut(value="execution(* pay(..))")
    public void pointcut() {}
    @Around(value="pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //1.记录日志
        //2.时间统计开始
        //3.安全检查
        Object retVal = pjp.proceed();//调用目标对象的真正方法
        //4.时间统计结束
        return retVal;
    }
}
//2 切入点
    @Pointcut(value="execution(* *(..))")
    public void pointcut() {}
    //3 拦截器的interceptor
    @Around(value="pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal=null;
        //预处理,前置条件判断
        boolean ok = true;
        if(!ok) {//不满足条件
           throw new RuntimeException("你没有权限");
        }
        else {//调用目标对象的某个方法
             retVal = pjp.proceed(); 
        }
        //后处理
        return retVal;
    }


AOP的基本概念
AOP是什么:
是一种编程范式
为开发者提供了一种描述横切关注点的机制
将那些与业务无关,却为业务模块所共同调用的逻辑或责任,封装起来
AOP能干什么:
降低模块的耦合度,使系统容易扩展,设计决定的迟绑定,更好的代码复


AOP的基本概念
连接点
表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP中表示为“在哪里做”
切入点:
选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法,在AOP中表示为“在哪里做的集合”
通知:
在连接点上执行的行为,通知提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置通知(before advice)、后置通知(after advice)、环绕通知(around advice),在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入通知;在AOP中表示为“做什么”
方面/切面:
横切关注点的模块化,比如上边提到的日志组件。可以认为是通知、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现;在AOP中表示为“在哪里做和做什么集合”
目标对象:
需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被通知的对象,从而也可称为“被通知对象”;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象,在AOP中表示为“对谁做”
AOP代理:
AOP框架使用代理模式创建的对象,从而实现在连接点处插入通知(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面
织入:
织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行
引入:
也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象), 在AOP中表示为“做什么(新增什么)”
前置通知:
在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)
后置返回通知:
在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
后置异常通知:
在方法抛出异常退出时执行的通知
后置最终通知:
当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
环绕通知:
包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结


AOP的基本运行流程:
找关键点
分离关注点
spring会根据切入点去匹配target中方法
当匹配到切入点方法,spring就会根据配置文件中aop的配置,来寻找对应的advice
织入


Spring事务管理-传统方案的问题:缺点:不一致的事务管理,复杂
Spring事务管理- Spring提供高层次解决方案:
//获取事务管理器
        PlatformTransactionManager txManager = (PlatformTransactionManager)             
             ctx.getBean("txManager");
        //定义事务属性
        DefaultTransactionDefinition td = new DefaultTransactionDefinition();
        td.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        //开启事务,得到事务状态
        TransactionStatus status = txManager.getTransaction(td);
        try {
            //执行数据库操作
            System.out.println(jdbcTempate.queryForInt("select count(*) from tbl_doc"));
            //提交事务
            txManager.commit(status);
            
        }catch (Exception e) {
            //回滚事务
            txManager.rollback(status);
        }


Spring事务管理- Spring高层次解决方案的好处:
一致的编程模型。
为复杂的事务API提供了一致的编程模型,如JTA、JDBC、Hibernate、JPA和JDO
声明式事务管理。
较少代码的入侵,以AOP的风格提供声明式事务管理
整合。
非常好地整合Spring的各种数据访问抽象


Spring事务管理- Spring事务管理实施步骤:这个和流程类似
定义(资源)。定义DataSource/SessionFactory等资源
定义事务管理器。根据不同的ORM框架,定义事务管理器(管理资源的事务)
定义事务通知。定义了如何实施事务(实施事务的方法名和对应的事务属性)
定义advisor。切入点选择需要实施事务的目标对象(一定是业务逻辑层)
织入事务通知。Spring织入事务通知到目标对象(AOP代理)


Spring事务管理-声明式事务具体的配置
定义数据源,定义数据访问,定义事务控制器,配置事物切面


Spring事务管理-重点属性-隔离级别( isolation )
Default UR CS RS RR
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题


默认事务定义都使用default,事务的隔离级别默认采用数据库连接池定义的级别


Spring事务管理-重点属性-传播机制(propagation) 
REQUIRED
如果没有事务,就建一个,如果有,就加入
SUPPORT
支持当前事务,如果当前没有事务,就以非事务的方式执行
MANDATORY
使用当前事务,如果当前没有,则抛异常
REQUIRED_NEW
新建事务,如果当前有事务,则挂起当前事务
NESTED
嵌套事务,存在savepoint概念,JDBC版本需要支持savepoint
NEVER
以非事务的方式执行,如果当前有事务,则抛出异常
NOT_SUPPORT
以非职务的方式执行,如果当前有事务,就挂起当前事务
<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" rollback-for="ServiceException" />
ServiceA:
<tx:method name="saveA*" isolation="DEFAULT" propagation=" REQUIRED" read-only="false" />
ServiceB:
<tx:method name="saveB*" isolation="DEFAULT" propagation=" REQUIRES_NEW" read-only="false" />


spring mvc
spring mvc框架简介,http请求地址映射,http请求数据的绑定,数据转换/格式化/校验,数据模型控制,视图及解析器


简介- Spring MVC框架结构
此处需要准备下框架图的结构
package com.baobaotao.web;
...
@Controller                           ① 将UserController变成一个Handler
@RequestMapping(“/user”)   ②指定控制器映射的URL
public class UserController {


@RequestMapping(value = “/register”) ③处理方法对应的URL,相对于
                                                                                    ②处的URL
public String register() {
         return “user/register”; ④返回逻辑视图名
}
}


地址映射-HTTP请求映射原理
http请求报文->web容器(spring mvc框架->handler处理方法)


地址映射-通过URL限定:URL表达式。对应2,可以有很多形式,如* ** {}


地址映射-通过URL限定:绑定{xxx}中的值
@RequestMapping("/{userId}")
@PathVariable(“userId”) String userId


地址映射-通过请求方法限定:请求方法
@RequestMapping(value=“/delete”)
public String test1(@RequestParam("userId") String userId){
    return "user/test1";
}
@RequestMapping(value="/delete",method=RequestMethod.POST) 


地址映射-通过请求/请求头参数限定:示例
@RequestMapping(value="/delete", params="userId") 
public String test1(@RequestParam("userId") String userId){
    ...
}
@RequestMapping(value="/show",headers="content-type=text/*")②
public String test2(@RequestParam("userId") String userId){
     ...
}


@RequestMapping(value="/handle2")
public String handle2(@CookieValue("JSESSIONID") String sessionId,
       @RequestHeader("Accept-Language") String accpetLanguage){
  ...
}


@RequestParam(value = "userName", required = false) //不能保证包含参数时,防止异常


数据绑定-使用命令/表单对象绑定
数据绑定-使用Servlet  API对象作为入参 HttpSession 
数据绑定-使用Spring的Servlet API代理类 WebRequest
数据绑定-使用IO对象作为入参  OutputStream
其它类型的参数:Locale locale


数据绑定- HttpMessageConverter<T>
HttpServletRequest <-> HttpMessageConverter<T> <-> @RequestBody/HttpEntity<T> @ResponseBody/ResponseEntity<T>


数据绑定-使用@RequestBody/@ResponseBody
       将HttpServletRequest的getInputStream()内容绑定到入参,将处理方法返回值写入到HttpServletResponse的getOutputStream()中。


数据绑定-使HttpEntity<T>/ResponseEntity<T>
httpEntity.getHeaders().getContentLength();  
re=new ResponseEntity<String>(return,headers, HttpStatus.OK);   


数据绑定-输出XML和JSON


数据处理-数据类型转换
Spring 3.0同时支持PropertyEditor和ConversionService 进行类型转换,ConversionService是Spring类型转换体系的核心接口


数据处理-强大的ConversionService,让很多梦想成真:
由于ConversionService在进行类型转换时,可以使用到Bean所在宿主类的上下文信息(包括类结构,注解信息),所以可以实施更加高级的类型转换,如注解驱动的格式化等功能。
public class User {
      @DateTimeFormat(pattern="yyyy-MM-dd")
      private Date birthday;
}


数据处理-数据校验框架
在Spring MVC中,则可直接通过注解驱动的方式进行数据校验。
        Spring的org.springframework.validation是校验框架所在的包
JSR 303是Java为Bean数据合法性校验所提供的标准框架
public class User {   
      @Pattern(regexp="w{4,30}")
      private String userName;

      @Length(min=2,max=100)
      private String realName;

     @Past 
     @DateTimeFormat(pattern="yyyy-MM-dd")
     private Date birthday;

    @DecimalMin(value="1000.00")
    @DecimalMax(value="100000.00") 
    @NumberFormat(pattern="#,###.##")
    private long salary;
}
 <mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean
使用:
@Controller
@RequestMapping("/user")
public class UserController {
     @RequestMapping(value = "/handle91")
     public String handle91(@Valid  User user,
                                          BindingResult bindingResult){
          if(bindingResult.hasErrors()){
               return "/user/register3";
          }else{
               return "/user/showUser";
          }
    }
}


数据处理-校验错误信息存放在什么地方??
4.Spring MVC将HttpServletRequest对象数据绑定到处理方法的入参对象中(表单/命令对象);
5.将绑定错误信息、检验错误信息都保存到隐含模型中;
6.本次请求的对应隐含模型数据存放到HttpServletRequest的属性列表中,暴露给视图对象。


模型控制-访问数据模型:ModelAndView
@RequestMapping(method = RequestMethod.POST)
public ModelAndView createUser(User user) {
userService.createUser(user);
ModelAndView mav = new ModelAndView();
mav.setViewName("user/createSuccess");
mav.addObject("user", user);
return mav;
}


模型控制-访问数据模型:@ModelAttribute
@RequestMapping(value = "/handle61")
public String  handle61(@ModelAttribute("user") User user){
user.setUserId("1000");
return "/user/createSuccess";
}


模型控制-访问数据模型:Map及Model
模型控制-访问数据模型:@SessionAttributes


模型控制-一场由@SessionAttributes引发的血案...
如果在会话中找不到对应的属性,则抛出HttpSessionRequiredException异常
模型控制-如何避免@SessionAttributes引发的血案
@ModelAttribute("user")
public User getUser(){
User user = new User();
return user;
}
该方法会往隐含模型中添加一个名为user的模型属性


模型控制- Spring MVC如何解析视图
模型控制-基于协商的视图解析器


模型控制-静态资源处理:使REST风格的URL成为实现
不希望带.htm等后缀


静态资源处理:原理
请求->spring mvc-> 静态资源->应用服务器默认servlet
请求->spring mvc-> 非静态资源->spring mvc 容器


模型控制-静态资源处理:如何配置?
第一步:web.xml让所有请求都由Spring MVC处理
第二步:springServlet-servlet.xml 让Web应用服务器处理静态资源


物理静态资源路径映射逻辑资源路径
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值