IOC 控制反转容器控制程序对象之间的关系,而不是传统实现中,有程序代码之间控制,又名依赖注入。All 类的创建,销毁都由Spring 来控制,也就是说控制对象生命周期的不是引用他的对象,而是Spring。对于某个对象而言,以前是他控制其他对象,现在是all 对象都被spring 控制,这就叫控制反转。
依赖注入的思想时通过反射机制实现的。在实例化一个类时,它通过反射调用类中的set
方法将事先保存在hashmap 中的类属性注入到类中。
Spring 实现aop:JDK 动态代理,cglib 动态代理。
JDK 动态代理:其代理对象必须是某个接口的实现,他是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。核心类有:InnovactionHandler,Proxy。
Cgib 动态代理:实现原理类似于jdk 动态代理,只是他在运行期间生成的代理对象是针对目标类扩展的子类。MethodInterceptor。
Get、post、head、delete、put、options、trace、connect。
MVC M:model entity 业务逻辑V:view 视图,用户看到并与之交互的界面C:controller 根据用户的输入,控制用户界面数据显示和更新model 对象状态功能模块和显示模块分离,提高可维护性,可复用性,可扩展性。
Hibernat 可以理解为一个中间件,他负责把java 程序的sql 语句接受过来并发送到数据库,而数据库返回来的信息由hibernate 接收后直接生成一个对象传给java。Hibernate 有1)一个配置文件cfg.xml,包括基本配置信息,比如数据库的操作,username,password,url,
driver 和format sql 和方言;2)还有一个映射文件hbm.xml 对数据控中表的映射。
Hibernate 一级缓存是必要的,位于session 部分,二级缓存则不是必须的,是由
sessionfactory 控制的进程级缓存,由开发人员自行指定。二级缓存可指定使用何种开源的
cache 工具。Hibernate3 以后的默认版本为Ehcache。查询时间缓存的过程1)查询一级缓存中是否有需要的额数据2)若没有,则查二级缓存3)若二级缓存中也没有,此时再执行查询数据库的操作。速度:一级>二级>数据库。
Hibernate 也会自行维护缓存中的数据,以保证缓存中的数据和数据库中的真实数据的一致性。无论如何,当你调用方法or 获取一个对象时,该对象都将被加入到session 的内部缓存中,当flush()方法最后被调用时,对象的状态会和数据库同步。也就是说。删除、更新、增加数据的时候,同时更新缓存。
Session 接口:复制执行被持久化对象的CRUD 操作(CRUD 的任务是完成与数据库的交流,包含很多的sql 语句)session 对象是非线程安全的。
Sessionfactory 接口:复制初始化hibernate,复制创建session 对象,他并不是轻量级的。通常一个项目,一个sessionfactory 对象。当需要操作多个数据库时,一个数据库,一个
sessionfactory。
Transaction 接口:与事务有关。
Query,criteria 接口:复制执行各种数据库查询,可使用sql 和hql。
Hibernate 的主键1)assign:由程序生成主键,且要在save()之前,否则抛出异常,特点是主键的生成值,完全由用户决定,与底层数据库无关。用户需要维护主键值,在调用
session.save()之前指定主键值。2)hilo:使用高低算法生成主键值,该方法需要额外的数据表和字段提供高位值来源,默认,使用表hibernate-unique-key。默认字段为next-hilo。特点:能保证同一个数据库主键的唯一性,但不能保证多个数据库中主键的唯一性。Hilo 与底层数据库无关,由hibernate 维护。3)increament:由hibernate 从数据库中取出主键的最大值,以该值为基础,每次增量为1,在内存中生成主键,不依赖于DB。4)sequence:采用数据库提供的sequence 机制生成主键,需要数据库支sequence,比如oracle,db2。Mysql 不支持。5)identity:由底层数据库生成标识符,identity 是有数据库自己生成的,但这个主键必须设置为自增长。使用identity 前提是数据库支持自动类型增长字段类型。比如:db2,mysql,sql server。Oracle 不支持。6)native:由hibernate 根据使用的数据库,自行判断采用hilo,
sequence,identity,其中一种作为主键生成方式。比如mysql 是identity,oracle 是sequence。
Hibernate 查询数据的方式:sql;query、criteria,以对象的方式添加查询条件;sql,直接使用sql 语句操作数据库。
JDBC 中,链接操作是是由Driver Manager 管理,JDBC 建立和关闭时及其耗资源的,
connection 接口实现链接数据库。JDBC 链接数据库分为4 部:1 )加载驱动
Class.forName(“con.mysql.jdbc.Driver”);2 )创建连接Connection
con=DriverManager.getConnection(url,username,password) ;3 )创建statement staticment s=con.createStatement() 4)执行sql s.executeQuery();
prepareStatement 是预先编译的语句,statement 不是防止sql 注入性能提高,
callableStatement:存储过程调用DatabaseMetaDate 类的很多方法都可以知道数据库中存储过程的详情。
servlet:是用于java 编写的服务器端程序,其使用java servlet API,当客户机发送请求到服务器时,服务器可以将请求信息发送给servlet,并让servlet 建立起服务器返回给客户机的响应。当启动web 服务器or 客户机第一次请求服务时,可以自动装入servlet,装入后,
servlet 继续运行直到其他客户机发出请求。
servlet 生命周期?Servlet 生命周期分为3 个阶段1)初始化阶段:调用init()方法2)响应客户请求:调用service()3)终止:调用destory().1)初始化阶段:在下列时刻servlet 容器装载servlet 1.servlet 容器启动时,自动装载某些servlet2. 在servlet 容器启动后,客户首次向 servlet 发送请求 3.servlet 类文件被更新以后,重新装载 servlet。Servlet 被装载后,servlet容器创建一个servlet 对象并调用servlet 的init 方法。在servlet 生命周期内,init()方法只被调用过一次。Servlet 工作原理:客户端发起一个请求,servlet 调用service()方法时请求进行响应,service 对请求的方式进行了匹配,选择调用dopost 或者doget 等这些方法,然后进入对应方法中调用逻辑层上的方法,实现对客户的响应。2)响应客户请求:对于用户到达
servlet 的请求,servlet 容器会创建特定于该请求的servletRequest 和servletresponse 对象,然后调用servlet 的service 方法,service 方法从servletrequest 对象中获得客户请求的信息,处理该请求,并通过servletresponse 对象向客户返回响应消息。3)终止:当web 应用终止或者servlet 容器终止或servlet 容器重新装载servlet 新实例时,servlet 容器会调用servlet 对象的第destory 方法,在destory 方法中可释放servlet 占用的资源。
tomcat 就是servlet 容器,servlet 容器为javaweb 应用提供运行时环境,它复制管理servlet
和jsp 的生命周期,以及管理他们的共享数据。
Servlet 生命周期以下方法:以下方法都由servlet 容器调用。1)构造函数:只有第一次请求servlet 时,创建servlet 实例,调用构造器,这说明servlet 是单例的,所以又线程安全问题,只被调用一次。2)init:只被调用一次,在创建好实例后,立即被调用,用来初始化
servlet3)service:被多次调用,每次请求都会调用service,实际响应请求。4)destory:只被调用一次,在当前servlet 所在的web 应用被卸载前调用,用于释放当前servlet 所占用的资源。
MVC1)m:model。Dao。与数据库打交道2)V:view, jsp 在页面上填写java 代码,实现显示3)C,controller,servlet 受理请求,获取请求参数,调用dao 方法,转发or 重定向页面。
Cookie 和session http 都是无状态的协议,web 服务器不能识别出哪些请求是同一个浏览器发的,浏览器的每一次请求都是完全独立的。
Cookie 放在浏览器端,浏览器第一次范围服务器时,没有cookie,then 服务器给浏览器一个cookie,以后每次浏览器访问服务器都要带上这个cookie。Jsp 是服务端
<% 1.创建一个cookie 对象Cookie cookie =new Cookie(“name”,”jhb”);
2.调用response 的一个方法把cookie 传输给客户端
Response.addCookie(cookie);
%>
默认情况下cookie 是会话级别,存储在浏览器内存中,用户退出浏览器之后被删除,若希望浏览器将cookie 存在磁盘上,则要使用maxage,并给一个以秒为单位的时间,表示
cookie 的存活时间。
Cookie 作用范围:可以作用当前目录和当前目录的子目录,但不能作用与当前目录的上一级。
Cookie:在客户端保持http 状态信息的方案,会话跟踪。
Session:在服务器端保持http 状态信息。
当浏览器第一次范围服务器时,没有cookie,服务器也就得不到JSession_id,then 服务器创建一个session 对象,并返回一个JSession_id 给浏览器,通过cookie 返回,下次浏览器再访问服务器时就带上cookie(其中有JSession_id),服务器就能找到对应的session 对象。JSession_id 可以通过cookie 传输,也可以通过url 传送。
一个session,对应一个sessionID。
Session:浏览器和服务器的一次会话,若浏览器不关,至始至终都是一个session,因为用cookie 传送。
URL 重写:response 的encodeURL(String URL) 方法和encoderedirectURL(String URL)两个都一样。
当程序需要为某给客户端的请求创建衣蛾session 时,服务器首先检查这个客户端的请求是否包含一个session 标识,即JSession_id,如果包含,则说明以前已经为此客户创建过
JSession_id,服务器就按照这个JSession_id 检索出来(若检索不到,可能会新建一个,这种情况下可能会出现在服务器已经删除了该用户对应的session 对象。但用户人为的在请求的
URL 上附加衣蛾JSession_id 的参数。)如不包含则创建一个session,并生成与这个session
有关的JSession_id,这个JSession_id 将在本次响应中返回给客户端。
默认session 用cookie。
若第一次访问某web 应用程序的一个jsp 页面,且该jsp 页面的page 指定session=true,服务器会创建一个httpsession 对象。
注:关闭浏览器只是使存储在浏览器内存中的session cookie 失效,不会使服务器端的
session 对象失效。
依赖注入:在运行期间由容器将依赖关系注入到组件中,就是在运行期,由spring 根据配置文件将其他对象的引用通过组将提供的setter 方法进行设定。控制反转:对组件对象控制权的转移,从程序代码本身转移到了外部容器,通过容器来实现对象组件的装配和管理。
SpringMVC
使用DispatcherServlet 进行分发,到达合适的额controller 。每个请求来到
dispatcherServlet,dispatcherServlet 来决定到哪个controller,通过handlermapping。先要在
web.xml 中配置dispatcherServlet 的和,在Servlet 中需要一个xml
文件,自己创建,里面来配置SpringMVC 的属性。
应用服务器:1)Tomcat:应用十分广泛的 web 服务器,支持部分 j2ee,免费,支持 servlet、
jsp。2)JBoss:开源应用服务器。3)Weblogic、webSphere:业界第一的appserver。4)Apache:全球应用最广泛的http 服务器,但只支持静态网页,比如asp、PHP 等动态网页不支持。
Memcached:是高性能分布式内存缓存服务器,本质是一个内存key-value 数据库,但不支持数据持久化,服务器关闭后,数据全丢失。只支持key-value 结构。
Redis:将大部分数据放在内存中,支持的数据类型有:字符串、hash 表、链表、集合、有序集合以及基于这些数据类型的相关操作。Redis 内部使用一个redisobject 对象来表示all
key 和value。
他们的区别:1)redis 中并不是all 数据都一直存储在内存中,这是和memcached 相比一个最大的区别。2)redis 不仅仅支持简单的key-value 类型的数据,同时还支持字符串、hash 表、链表、集合、有序集合。3)redis 支持数据备份,即master-slave 模式的备份。4)redis 支持数据的持久化,可以将内存中的数据保存在磁盘上,重启的时候可以再次加载进内存使用。Memcached 服务器关闭后,数据丢失。5)memcached 挂掉后,数据不可以恢复,redis 数据丢失后可通过AOF 恢复(灾难恢复)。
Spring1)ioc 容器——BeanFactory 是最原始的ioc 容器,有以下方法1.getBean2.判断是否有Bean,containsBean3.判断是否单例isSingleton。BeanFactory 只是对ioc 容器最基本行为作了定义,而不关心Bean 是怎样定义和加载的。如果我们想要知道一个工厂具体产生对象的过程,则要看这个接口的实现类。在spring 中实现这个接口有很多类,其中一个
xmlBeanFactory。xmlBeanFactory 的功能是建立在DefaultListablexmlBeanFactory 这个基本容器的基础上的,并在这个基本容器的基础上实行了其他诸如xml 读取的附加功能。xmlBeanFactory(Resource resource)构造函数,resource 是spring 中对与外部资源的抽象,最常见的是文件的抽象,特别是xml 文件,而且resource 里面通常是保存了spring 使用者的
Bean 定义,eg.applicationContext.xml 在被加载时,就会被抽象为resource 处理[我自己理解,
resource 就是定义Bean 的xml 文件]。
loc 容器建立过程:1)创建 ioc 配置文件的抽象资源,这个抽象资源包含了 BeanDefinition的定义信息。2)创建一个BeanFactory,这里使用的是DefaultListablexmlBeanFactory。3)创建一个载入BeanDefinition 的读取器,这里使用xmlBeanDefinitionReader 来载入xml 文件形式的BeanDefinition。4)然后将上面定义好的resource 通过一个回调配置给BeanFactory。
5)从资源里读入配置信息,具体解析过程由xmlBeanDefinitionReader 完成。6)ioc 容器建立起来。
BeanDefinition 类似于resource 接口的功能,起到的作用就是对所有的Bean 进行一层抽象的统一,把形式各样的对象统一封装为一个便于spring 内部进行协调管理和调度的数据结构。BeanDefinition 屏蔽了不同对象对于spring 框架的差异。
Resource 里有inputStrea。
解析xml,获得document 对象,接下来只要再对document 结构进行分析便可知道Bean
在xml 中是怎么定义的,也就可以将其转化为BeanDefinition 对象。我们配置的Bean 的信息经过解析,在spring 内部已经转换为BeanDefinition 这种统一的结构,但这些数据还不能供ioc 容器直接使用,需要在ioc 容器中对这些BeanDefinition 数据进行注册,注册完成的BeanDefinition,都会以BeanName 为Key,BeanDefinition 为value,交由map 管理。注册完之后,一个ioc 容器就可以用了。
自己理解的,xml 文件抽象为resource 对象,Bean 抽象为BeanDefinition 对象。
2)依赖注入——依赖注入发生在getBean 方法中,getBean 又调用dogetBean 方法。
getBean 是依赖注入的起点,之后调用createBean 方法,创建过程又委托给了docreateBean
方法。在docreateBean 中有两个方法:1)createBeanInstance,生成Bean 包含的java 对象
2)populateBean 完成注入。在创建Bean 的实例中,getInstantiationstrategy 方法挺重要,该方法作用是获得实例化策略对象,也就是指通过哪种方案进行实例化的过程。spring 当中提供两种方案进行实例化:BeanUtils 和cglib。BeanUtils 实现机制是java 反射,cglib 是一个第三方类库,采用的是一种字节码加强方式。Spring 中默认实例化策略为cglib。populateBean 进行依赖注入,获得BeanDefinition 中设置的property 信息,简单理解依赖注入的过程就是对这些property 进行赋值的过程,在配置Bean 的属性时,属性可能有多种类型,我们在进行注入的时候,不同类型的属性我们不能一概而论地进行处理。集合类型属性和非集合类型属性差别很大,对不同的类型应该有不同的处理过程。所以要先判断value 类型,再调用具体方法。
3)aop——将那些与业务无关,却为业务模块所公共调用的逻辑或责任封装起来,称其
为aspect,便于减少系统的重复代码。使用模块技术,aop 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。实现aop 的两大技术:1)采用动态代理,利用截取消息的方式,对该消息进行装饰,以获取原有对象行为的执行。2)采用静态织入,引入特定的语法创建切面,从而可以使编译器可在编译期间织入有关切面的代码。
spring 提供两种方式生成代理对象,jdkProxy 和cglib。默认的策略是,若目标类是接口则用jdk 动态代理技术,否则使用cglib 生成代理。在jdk 动态代理中使用
Proxy.newProxyInstance() 生成代理对象( JdkDynamicAopProxy 类的getProxy 方法),
JdkDynamicAopProxy 也实现了invocationhandler 接口,有invoke 方法,就是在该方法中实现了切片织入。主流程可以简述为:获取可应用到此方法上的通知链(Interceptor chain),若有,则应用通知,并执行joinpoint,若没有,则直接反射执行joinpoint。
Introduction 是指给一个已有类添加方法或字段属性,Introduction 还可以在不改变现有类代码的情况下,让现有java 类实现新的接口,或为其指定一个父类实现多继承,相对于
advice 可以动态改变程序的功能或流程来说,Introduction 用来改变类的静态结构。
拦截器,是对连接点进行拦截,从而在连接点前后加入自定义的切面模块功能。作用于同一个连接点的多个拦截器组成一个拦截器链,拦截器链上的每一个拦截器,通常会调用下一个拦截器。
连接点,程序执行过程中的行为,比如方法调用或特定异常被抛出。
切入点,指定一个advice 将被引发的一系列的连接点的集合。aop 框架必须允许开发者指定切入点。
通知(advice):在特定的连接点,aop 框架执行的动作。Spring 以拦截器作通知模型,维护一个围绕连接点的拦截器链。
拦截器(advisor),自己理解,在invoke 前后加入的方法就是通知。使用spring 的
PointCutadvisor,只拦截特定的方法,一个advisor 定义订一个PointCut 和一个advice,满足PointCut(指定哪些方面需要拦截),则执行相应的advice (定义了增强的功能)。PointCutadvisor 有两个常用实现类:NameMatchMethodPointCutadvisor 和
regexMethodPointCutadvisor。前者需要注入mappedname 和advice 属性,后者需要注入
pattern 和advice 属性。mappedname 指明要拦截的方法名,pattern 按照正则表达式的方法指明了要拦截的方法名,advice 定义一个增强,即要加入的操作(需要自己实现MethodBeforeAdvice、MethodafterAdvice、throwAdvice、Methodinterceptor 接口之一),然后在ProxyBeanFactory 的拦截器中注入这个PointCutadvisor。注:一个ProxyFactoryBean 只能指定一个代理目标。
在spring 中配置aop 很麻烦,首先需要编写xxxadvice 类(需要自己实现
MethodBeforeAdvice、MethodafterAdvice、throwAdvice、Methodinterceptor 接口之一),然后在xml 配置advisor。还要在advisor 中注入advice,然后将advisor 加入ProxyFactoryBean 中。而在spring2.x 以后引入了aspect J 注解,只需要定义一个aspect 类,在aspect 中声明
advice 类(可同时声明多个),然后在xml 配置这个aspect 类,最后添加一行就可以搞定。
通知类型接口描述
前置通知MethodBeforeAdvice在目标方法调用前调用
后置通知MethodafterAdvice在目标方法调用后调用
异常通知throwAdvice在目标方法抛出异常时调用
环绕通知Methodinterceptor拦截对目标方法调用
还有一类是引入通知,用来定义切入点的。
@RestController 注解相当于@RequestBody+@controller 合在一起的作用。1)若只使用
@RestController 注解,则controller 中的方法无法返回jsp ,页面配置的视图解析器
viewResolver 不起作用,返回的内容就是return 里的内容。比如:本来应该到success.jsp 页面的,但其显示为success。2)若需要返回指定页面,则要使用@controller 和viewResolver
结合。3)若要返回Json,则要在方法上加@RequestBody。
都用过哪些注解:@controller、@service、@Requsetmapping、@transactional、@ RequestBody、
@compnent、@autowired、@cookievalue 、@repository、@RestController。其中@controller、
@service 负责注册一个bean 到spring 上下文中,bean 的id 默认为类名称开头字母小写。
@autowired 根据bean 的类型从spring 上下文进行查找,注册类型必须唯一。@pathvariable 一个函数里有一个输入参数,就是{seckillId}的值就用pathvariable。
Nginx:可以根据客户端的ip 进行负载均衡,在upstream 里设置ip_path,负载均衡五种配置:1)轮询(默认),每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down 掉,能自动剔除;2)指定权重,指定轮询几率。权重越大,轮询几率越大,用于后端服务器性能不均的情况。3)ip 绑定ip_path,每个请求按访问ip 的哈希结果分配,这样每个客户固定访问一个服务器,可以解决session 问题。4)fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。5)url_hash 按访问的url 结果来分配请求,使每个url 定位到同一个后端服务器。后端服务器为缓存时比较有效。具体的配置自己网上百度。
Spring 用事务管理器来管理事务,有一套统一的api,对于不同持久化方式有不同实现,
比如jdbc、hibernate。
TransactionDefinition 类用来定义事务的属性。
1)传播行为,有7 种。propgation_required:支持当前事务,若当前没有事务,则创建一个事务;propgation_supports:支持当前事务,若当前没有事务,则以非事务方式执行;
propgation_mandatory:支持当前事务,若当前没有事务,则抛异常;propgation_required_new:新建事务,若存在当前事务,把当前事务挂起;propgation_not_supported:以非事务的方式执行,若存在当前事务,则把当前事务挂起;propgation_never:以非事务的方式运行,若存在当前事务,则抛异常;propgation_nexted:若当前事物存在,则嵌套事务执行。
2)隔离级别
3)它是否为只读事务。
4)事务超时:为了使应用程序很好的运行,事务不能运行太长时间,因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源,事务超时就是事务的一个定时器,在特定时间内事务没有完成,那么就会自动回滚,而不是一直等待其结束。
5)回滚规则:默认情况下,事务只会遇到RuntimeException 才回滚。
声明式事务基于aop,配置事务:@transaction+事务管理器。
Java web1)前端(html、css、js、bootStrap、jquery);2)java web 核心(servlet、tomcat、
cookie);3)redis。
get 请求在url 中发送,post 请求在http 消息主体中发送。
Session:可以放在服务器内存、文件或数据库中。如何实现session 共享:1)通过组播的方式进行集群间共享,当一台机器上的session 变更后会将变更的数据以组播的方式分发给集群中所有其他节点。2)利用NFS 等共享存储来共享session,用一台nfs 服务器或数据库来放session,缺点:nfs down 掉。3)利用memcached 或redis 来共享,所有web 服务器
都把session 写入memcached 或redis,也都从memcached 或redis 来取。优点:网络开销小,几乎没有io;缺点:受限于memcached 容量。memcached 本来就是分布式。
每定义一个servlet,都必须实现servlet 接口。genericservlet 实现了该接口,不限于任何协议,httpservlet 受限于http 协议。
Filter——1)目的:调用目标资源前让一段代码执行,是否允许用户调用目标资源,调用目标资源之后让一段代码执行。2)编写java 类,实现filter 接口,配置filter-mapping,说明对哪些资源进行拦截。3)每次拦截时,都调用filter 的dofilter 方法。4)filter 创建和销毁由servlet 容器,在web 应用启动时,创建实例,并调用init 方法,filter 对象只创建一次,init 只执行一次。Destory,容器卸载filter 对象前被调用。5)用户在配置filter 时,可以使用为filter 配置一些初始化参数,当web 容器实例化filter 对象时,调用其
init 方法,会把封装了filter 初始化参数的filter config 对象初始化,所以开发人员在写filter 时,可以用filter config 对象的方法来获得初始化对象。6)应用:统一全站的字符编码;禁止浏览器缓存;实现url 级别的权限认证。
jsp 引擎就是servlet 程序。
Jsp 转译为servlet 源文件,然后编译为servlet 的class 文件。动态:先编译后包含;静态:先包含后编译。
Hibernate 持久化对象的生命周期1)临时状态(transient),也称为自由状态,他只存在于内存中,且在数据库中无相应的数据。2)持久化状态(Persist),与session 关联,且在数据库中有对应数据。3)游离状态(detached),已经持久化,但不在session 缓存中。
持久化游离暂时
是否处于 session 缓存中有无无
数据库中是否有记录有有无
最小生成树不唯一。
Hibernate.cfg.xml 和Hibernate.hbm.xml
Hibernate 一级缓存(session 缓存)是事务级别的,每个事务(session)都有单独的一级缓存。这一级别的缓存是由hibernate 进行管理。一般情况下无须进行干预。每个事务都有单独的一级缓存,不会出现并发问题,因此无须提供并发访问策略。
一级或二级缓存,若查询的是对象的属性,则不会把对象加入缓存中。
双亲委派模型是通过loadclass 方法实现:先检查类是否被加载过,若没有,则调用父类加载器的loadclass 方法,若父类加载器为空,则使用启动类加载器为父类加载器。若父类加载器加载失败,先抛出classNotFoundException,然后调用自己findclass 方法进行加载。
要实现自定义类加载器:只需要继承java.lang.classLoader。
sprigMVC 运行原理1)客户端请求提交到DispatcherServlet。2)由DispatcherServlet 控制器查查询一个or 多个handlermapping,找到处理请求的controller。3)DispatcherServlet 将请求提交给controller。4)controller 调用逻辑处理完后,返回methodAndView。5)
DispatcherServlet 查询一个or 多个ViewResolver 视图解析器,找到modleAndView 指定的视图。6)视图负责将结果显示到客户端。
Spring 实例中的成员注入:1)若改变量有set 方法,用property。2)若改变量没有set
方法,用constructior-args。
Redis 是Nosql 数据库系统,高并发,高性能面向key/value。
系统架构师是一个既需要控制整体,又需要洞悉局部瓶颈,并依据具体的应用场景给出解决方案的人。确定和评估需求,给出开发规范。在需求阶段,负责理解和管理非功能性需求(可维护性、可复用性),还需要确定客户及市场人员所提出的需求,确定开发团队所提出的设计。在软件设计阶段,负责对软件体系结构关键构件、接口。在编码阶段,详细设计者和编码者的顾问,并且经常举行技术研讨会。随着集成和测试,集成和测试支持将成为软件架构师的工作重点。
web service 技术:1)XML+XSD:web service 采用http 协议传输数据,采用xml 格式封装数据(xml 中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么).xml 易建立、易分析、与平台无关。Xsd:sml schema:定义了一套标准的数据类型,当你用某种语言(java、c++等)来构造一个web service 时,为了符合web service 标准,所有你使用的数据类型都必须被转换为xsd 类型(你用的功能可能已经帮你自动完成了这个转换);2)soap,soap 协议=http 协议+xml 数据格式;3)wsdl:比如我们去商店买东西,首先要知道商店里有什么东西可买,然后再买,商店的做法是贴张海报。web service 也一样,web service 客户端要调用一个web service 服务,首先要知道这个服务的地址在哪里,以及服务里有什么方法可调用,所以web service 服务器首先要通过一个wsdl 文件说明自己家里有什么服务可以对外调用,服务是什么(服务中有哪些方法、参数)。wsdl 就是一个基于
xml 语言,用于描述web service 及其函数、参数和返回值。
Hibernate——1)一级缓存session:hibernate 内置,不能卸除。缓存范围:缓存只能被当前session 对象访问,缓存的生命周期依赖于当前session 的生命周期,session 关闭后,缓存也就没有了。2)二级缓存sessionfactory:使用第三方插件。缓存范围:被应用内所有
session 共享,缓存生命周期依赖于应用的生命周期。
xml 解析技术?答案:1)dom:必须在解析之前把整个文档装入内存,处理大型文件时,性能低,适合xml 随机访问。2)sax:事件驱动,它顺序读取xml 文件,不需要一次全部载入整个文件。当遇到文件开头,文档结束or 标签开头or 标签结束时,他会触发一个事件,用户通过在其回调事件中写入处理代码来处理xml 文件,适合顺序访问。
聚集索引:返回适用于某范围内的数据。接口:定义与实现分离。
面向接口编程优点:1)接口经过合理设计之后,有助于程序设计的规范化,可以并行开发,提高工作效率;2)实现了程序的可插拔性,降低耦合度。
forword VS redirect 区别1)forward 是服务器请求资源,服务器直接访问目标地址的url,把url 的响应内容读取出来,然后把这些内容发送给浏览器,浏览器根本不知道服务器发送的内容是从哪取出来,所以他的地址栏中还是原来的地址。Redirect 服务器根据逻辑发送一个状态码,告诉浏览器重新去请求事先访问过的那个地址,一般来说,浏览器会用刚才请求的all 参数重新请求,所以session,request 参数都可以获取。地址栏显示的是新的url。用redirect 等于客户端向服务器端发两次request,同时也接受两次response。2)forward:转发页面和转发到的页面可以共享request 的数据;redirect 不能共享数据3)forward:只能在同一个web 应用程序之间转发请求;redirect:不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至使用绝对url 重定向到其他站点的资源。4)forward:/代表当前web 应用根目录redirect:/代表当前web 站点的根目录。
JSP 内置对象。1)request:用户端的请求,此请求会包含来着get or post 请求的参数。
2)response:网页传回用户端的响应。3)pageContext:网页的属性4)session:与请求有关的会话5)application:servlet 正在执行的内容6)out:传送回应的输出7)conig:servlet 的部件8)page:gsp 网页本身9)exception:网页错误
jsp 有哪些动作?6 个1)jsp:include 在页面被请求时,引入一个文件2)jsp:useBean 寻找or 实例化一个JavaBean3)jsp:setProperty 这只javaBean 的属性4)jsp:getProperty 输出某个javaBean 的属性5)jsp:forword 把请求转到一个新页面6)jsp:plugin 根据浏览器类型为
java 插件生成object or embed 标配。
jsp 中动态include 与静态include 区别?答案:动态include 用jsp:include 动作实现,它总是会检查所包含文件中的变化,使用于包含动态页面;静态include 用include 伪码实现,不会检查所含文件的变化,适用于包含静态页面。
前者页面不会转向include 所指向的页面,只显示该页的结果,主页面还是原来的页面,指向完以后还会回来,相当于函数调用,并且可以带参数。后者完全转向新页面,不会再回来,相当于goto 语句。
servlet VS CGI 区别1)servlet 可移植跨平台CGI 不行2)在传统CGI 中每个请求都要启动一个新进程,若CGI 程序的本身执行时间较短,启动进程所需要的进行所需要的开销很可能反而超过实际执行的时间;servlet,每个请求由轻量级的java 线程处理3)在传统CGI 中,若有N 个并发的对同一个CGI 的请求,该CGI 的程序代码在内存中重载了N 次,对于servlet,处理请求的是N 个线程,只要一份servlet 类代码。
如何实现servlet 单线程模式?答案:要实现单线程模式,可以在配置文件中修改
isThreadSafe 属性,比如,<%@page isThreadSafe=”false”%>
servlet 页面间对象传递的方法有几种?答案:用request,session,application。Cookie
等方法实现页面间的对象传递。
jsp VS servlet:jsp 是servlet 技术的扩展,本质上是servlet 的简单方式,jsp 编译后是“类
servlet”。他们最主要额不同在于:servlet 的应用逻辑在 java 文件中,并且完全从表示层中的html 分离出来。Jsp 是java 和html 可以组合为一个扩展名为.jsp 的文件。Jsp 侧重视图,
servlet 侧重控制逻辑。
J2ee 号称多层结构,为什么多层比两层好?答案:多层结构解耦性好,使得维护与扩展方便,灵活。
典型的j2ee 至少划分为3 层:表现层、业务逻辑层、持久层。
测试1)语句覆盖:至少每个语句应该执行一次,最弱的逻辑覆盖标准。2)判定覆盖:每个判定的每种可能结果都要执行一次,建立判定表之后,要保证每种判定的结果中都包含了T 和F。3)条件覆盖:不但每个语句要执行一次,而且判定表达式中的每个条件都要取到可能的结果,建立判定表以后,要保证每种条件的结果中包含了T 和F。4)判定-条件覆盖:每个判定及每个判定中的每个条件都取到可能的结果,建立判定表后,要保证每个判定结果包含T 和F,而且每个条件的结果包含T 和F,也就是综合了上面的判定覆盖和条件覆盖。5)条件组合覆盖:每个判定中的条件的各种组合至少出现一次,也就是说,先把程序中的条件列出来,排列组合写出all 可能性,看有没有哪些值同时满足这些排列组合。6)路
径覆盖:每条可能的路径至少执行一次。
功能测试:也称为黑盒测试,只考虑各个功能,不考虑整个软件的内部结构及代码。可用性测试:用户在和系统交互时对用户体验质量的度量,由用户测试。
边界测试就是找到边界,then 在边界附近(两边)选点。
3,16,37,?,289 应该填100,因为16-3=7,37-16=21, 100-37=63,289-100=189
2012!末尾有几个0?答案:乘机会产生0 的就是2 的倍数与5 的倍数相乘产生的。
2012/5=402,402/5=80,80/5=16,16/5=33,402+80+16+3=501,所以末尾公有501 个0.
tomcat 服务器默认端口8080,启动tomcat 用bin 目录下的startup.bat--用的是catalina.bat.
jsp 中 java 代码写在<% %>中。
Load-on-startup:配置在servlet 节点中,用来指定servlet 实例被创建的时机。若为负数,则在第一次被请求时创建,若为0 或正数,则在当前web 应用被servlet 容器加载时创建实例,且数值越小则越早被创建。
一个servlet 可以有多个servlet-mapping 对其进行映射。
Servletconfig:init 函数的参数,他封装了 servlet 的配置信息,并且可以获得 servletContext
对象。
Servlet 引擎为每个web 应用创建一个servletcontext 对象,一个web 应用程序中all servlet
都共享一个servletcontext 对象,他对应一个web 应用。
Servletrequest 里封装了all 有关请求的信息,但要看是get 方式还是post 方式,必须用
httpservletrequest 的getMethod()方法。
Jsp 可以放在web 应用程序中除了web-inf 中。每个jsp 页面在第一次被访问时,jsp 引擎将它翻译为一个servlet 源程序,接着再把这个servlet 源程序编译成servlet 的class 文件,然后再由web 容器(servlet 引擎)像调用普通servlet 程序一样来装载和解释这个由jsp 页面译成的servlet 程序。
Jsp 九个内置对象。1)request:httpservletrequest2)response:httpservletresponse,在
jsp 页面中几乎不用response 任何方法3)pagecontext:页面的上下文,是pagecontext 的一个对象,可以从该对象获得其他8 个对象及页面的其他信息。4)session:代表浏览器和服务器的一次会话,是httpsession 对象。5)application:代表当前web 应用,是servletcontext 对象。6)config:当前 jsp 对应的 servlet 的 servletconfig 对象,开发时几乎不用 7)out:jspWriter对象,调用out.println()可以直接把字符串打印到浏览器。8)page:只能调用object 方法,开发时几乎不用,指向当前jsp 对应的servlet 对象的引用。9)exception:在声明了page 指
令的 iserrorpage=“true”时才可以使用。
Jsp 注释<%-- --%>
和属性相关的方法1)object getAttribute(String name):获取指定的属性2)Enumeration
getAttributenames(): 获取all 的属性的名字组成一个enumeration 对象3)removeAttribute(String name):移除指定的属性4)setAttribute(String name,Object 0):设置属性。
pageContext,request,session,application 对象都有这些方法,这4 个对象为域对象。
Pagecontext:属性的作用范围仅限于当前jsp 页面。Request:属性的作用范围仅限于同一个请求。Request:属性的作用范围限于一次会话。浏览器打开直到关闭称之为一次会话(在此期间会话不失效)。Application:属性的作用范围限于当前web 应用,是范围最大的属性作用范围。只要在一处设置属性,在其他jsp 和servlet 中都可以获取到。
请求重定向VS 请求转发1)请求httpservletrequest 的getrequestDispatcher()方法,获取
requestDispatcher 对象,调用该方法时,传入需要转发的地址2)调用requestDispatcher 的
forword(request,response)进行请求的转发。
请求重定向,两次请求,直接调用response 的sendredirect(path) 方法。
Resp.sendRedirect(location)。
Jsp 指令<%@ %> <%@include %>静态引入嵌入整个源码,生成一个 servlet 源文件。Jsp 指令是为 jsp 引擎设计的,只是告诉 jsp 引擎如何处理 jsp 页面中的相关部分。
pageEncoding:指定当前页面的字符编码charset:指定返回页面的字符编码。
动态引入生成两个servlet 源文件。
Java 中中文乱码问题1 )在jsp 页面上出入中文,提交页面后不出现乱码
pageEncoding,charset 的编码一致,且都支持中文,建议为 utf-8,还需要保证浏览器显示的字符编码也和请求的 jap 编码一样。2)获取参数中的中文,默认参数在传输过程中使用iso-8859-1 1. 对于post 请求:值需要在获取请求信息之前调 用request.setCharacterEncoding(“utf-8”) 2. 对于 get 请求, String username =new String(val.getBytes(iso-8859-1),”utf-8”),先用 iso-8859-1 解码,再用 utf-8 编码。
多个请求映射到同一个jsp 页面?答案:1)这几个请求的名字都为xxx.do,all 以.do 结尾的都映射到同一个servlet。2)用request 获得path,即/xxx.do。3)去掉后面的.do 和前面的”/”,得到方法名,即xxx。4)利用反射调用相关方法。
Httpsession 生命周期:1)什么时候创建httpsession?答案:1.是否浏览器访问服务器的任何一个jsp 或者servlet,服务器都会创建一个httpsession?不一定,设置session=false,若当前jsp 是客户端访问的当前web 应用的第一个资源,且page 指定的session=false,则服务器不会为jsp 创建session 对象。若当前jsp 不是客户端访问的当前web 应用的第一个资源,且其他页面已经创建了其他httpsession 对象,则返回一个和当前会话相关的httpsession 对
象,不创建一个新对象。2.session=false 是什么意思?当前jsp 页面禁用session 隐含变量,但可以使用其他的显示的httpsession 的对象。3.对于servlet,若servlet 是客户端访问的第一个web 应用资源,只有调用request.getSession()或除了1 和2 以外,只要访问jsp,则要创建session 对象。2)什么时候销毁session 对象?答案:1.直接调用httpsession 的
invalidate 方法,该方法使httpsession 失效。2.当前web 应用被卸载。3.超出httpsession 的过期时间。
建议使用绝对路径,在java 中什么是绝对路径?相对于当前web 应用根路径的路径。
JavaBean:就是一个特殊的java 类,用作javaBean 的类必须具有一个公共的无参数的构造函数,Setter 和getter。javaBean 的属性名是根据setter 和getter 来生成,且首字母必须小写。
EL 表达式 Expression Language 表达式语言 all 的 EL 都以${ }开始。
EL 隐含对象11 个1)和范围有关application scope,session scope ,request scope,pagescope 2 )和输入有关param ,paramValues 3 )其他隐含对象cookie ,header ,
headerValues,initparam,pageContext 。
自定义标签:1)先写一个标签处理器类,实现 simpleTag 接口,或者继承 SimpleTagSupport类。2)建一个tld 文件,一个描述文件。3)在jsp 中使用自定义标签。4)在jsp 页面中使用jsp 标签<%@ taglib %>引入。
jspFragment 封装jsp 标签体。jspFragment.invoke(writer out)。
若配置的标签有标签体,则jsp 引擎会调用setjspBody()方法把jspFragment 传递给标签处理器,我们可以使用SimpleTagSupport 的getjspbody 方法来返回jspFragment。
子标签作为父标签的标签体存在,父标签无法获取子标签引用,但子标签可以获取父标签引用。
El 自定义函数1)写一个静态函数实现功能2)tld 文件中配置
JSTL(jsp 标准便签函数库):使页面上没有java 代码,用el 或jstl 或其他自定义标签。
必须是和的父标签且在同一个,必须在之前。
为循环控制,它可以将集合collection 中的成员循环浏览一遍,运行方式为当前条件符合时,就会持续重复执行的本体内容。
Filter 过滤器filter 的基本功能是对servlet 容器调用servlet 的过程进行拦截,从而在
servlet 进行相应处理的前后实现一些特殊功能。Filter 程序是一个实现了Filter 接口的Java
类,他由 servlet 容器进行调用和执行。Servlet 容器 filter servlet。
Filter 1)init()方法类似于servlet 的init 方法,创建filter 对象后,立即被调用,且只被
调用一次。Filter 对象在servlet 容器加载当前web 应用程序时就被创建。Filter 实例是单例的。2)doFilter()方法,逻辑代码写在这里面,每次拦截器都会调用的方法。他有3 个参数,servletrequest,servletresponse,filterchain(指filter 链,多个filter 可构成一个filter 链,
filterchain 只有一个方法doFilter(request,response),把请求传给filter 链的下一个filter,若当前filter 是filter 链的最后一个filter,将把请求传给目标servlet(or jsp))。若有多个filter 满足要求,则拦截顺序与web.xml 中的filter-mapping 的配置顺序有关。先配置先调用。3)
destory:释放当前filter 所占用的资源,filter 销毁之前被调用,且只被调用一次。
与开发servlet 不同,Filter 接口并没有相应的实现类可以继承,要开发过滤器,只能直接实现filter 接口。
多个filter 代码的执行顺序
HelloFilter 的doFilter 方法有3 个方法
S.O.P(before hello);
doFilter();//调用的是secondFilter 的doFilter 方法
S.O.P(after hello);
secondFilter 的doFilter 方法有3 个方法
S.O.P(before second);
doFilter();//调用的是jsp 的doFilter 方法
S.O.P(after second);
jsp 的doFilter 方法
<% S.O.P(test jsp);%>
这5 个输出语句的执行顺序是:
S.O.P(before hello); S.O.P(before second); S.O.P(test jsp); S.O.P(after second); S.O.P(after hello);
Filter 的dispatcher 节点(表明拦截哪种方式的页面)默认为request,还可以的取值有
forward,error,include。Request:直接发get 或post 请求,当用户直接访问页面时,web 容器将会调用过滤器。Include:若目标资源是通过requestdispatcher 的include 方法访问,则该过滤器将被调用。Forword:1) 2)requestdispatcher.forword 3)通过 page 指令的errorpage 转发页面。Error:若目标资源是通过声明式异常处理机制调用时,则该过滤器将被调用。Dispatcher 节点可以有多个。
Filter 的应用:1)禁用浏览器的缓存。2)字符编码过滤器。若没有过滤器则在每一个请求页面中都要写request.setCharacterEncoding,有了filter,对于all 请求都经过filter,只需要写一次。3)检测用户是否登录的filter。
Filter 是javaweb 的一个重要组件,可以对发送到servlet 的请求进行拦截,并对相应也进行拦截。
URL:http://localhost:8080/day_01/login/a.jsp(其中day_01 为工程名字)
URI: day_01/login/a.jsp Servletpath:login/a.jsp
JavaWeb-servlet 监听器
监听器:专门用与对其他对象身上发生的事件或状态的改变进行监听or 相应处理的对象。当被监视的对象发生情况时,立即采取相应的行动。
Servlet 监听器:一种特殊的类,用于箭筒ServletContext,httpsession,Servletrequest 等域对象的创建与销毁事情,以及监听这些对象中的属性发生修改的事件。
一、监听域对象的创建和销毁
创建时间销毁时间
ServletContext(application)
毁
web 应用被加载web 应用被销
Httpsession(session)
Servletrequest(request)
每次请求开始时创建
每次访问结束后销毁
ServletContextListener 最为常用,监听ServletContext 对象创建or 销毁的Servlet 监听器,可以在当前web 应用被加载时对当前web 应用的相关资源进行初始化,比如:创建数据库连接池。HttpsessionListener:sessioncreated 在 session 被创建后调用,sessionDestoryed 在 session被销毁前调用。
生命周期:1)request:是一个请求,当一个相应返回时被销毁,发一个请求时被创建
[if !supportLists]1. [endif]forword 只有一个请求,只有一个request 2.response 有两个request。2)session:当第一次访问web 应用的一个jsp 或Servlet 时,且该jsp 和Servlet 中还需要创建session 对象,此时服务器会创建一个session 对象。3)application:ServletContext 对象。当前web 应用被加载时创建,web 应用被卸载时销毁。
二、域对象中属性的变更的试卷监听器变更:添加,置换,删除。
要使用监视器:写一个类,实现相对应的接口,在web.xml 中配置。
三、感知session 绑定的事件监听器,不用再web.xml 中配置
1)实现了httpsessionBindingListener 的javabean 可以感知自己是否放入session 属性中or
被移出,有两个方法
[if !supportLists]1. [endif]public void valueBound():当前对象被绑定到session 时调用。
[if !supportLists]2. [endif].public void valueUnbound():当前对象从session 中解除绑定时被调用。
2)活化:从硬盘里读出钝化:把自己写入硬盘
实现了httpsessionActivationListener 可感知自己被活化or 钝化。
关了web 服务器,session 本应该销毁,但有一个缓存机制,把session 存放在tomcat 服务器的work/catalane/localhost/contextpath 目录下session,ser。
集群1)伸缩性:系统适应不断增长的用户数的能力。2)高可用性:避免单一服务器的单点失效.3)负载均衡:把请求发给不同服务器。4)失效转移:当一个节点失效后,通过选择集群中的另一个节点,处理将会继续而不会终止。httpssession 失效转移,用来保证当某台服务器失效以后,会话状态不会丢失,为了支持会话转移,web 服务器将在一定的时候把会话对象备份到其他地方,以防丢失。这个其他地方有jdbc 数据库、其他所有服务器、任意选择其他一台web server、中央server。
GetVSPost——get 提交的信息显示在地址栏不安全对大数据不行(因为地址栏存储体积有限)获取/查询资源;Post 提交的信息不显示在地址栏安全对大数据可以更改信息
断言是软件开发中一种常用的调试方式,在实现中,assertion 就是在程序中的一条语句,他对一个布尔表达式进行检查,一个正确的程序必须保证这个boolean 表达式的值为true,若该值为false,则说明程序已经处于不正确的状态下,系统将给出警告并退出。
什么时候使用断言?可以在预计正常情况下不会到达的任何位置上放置断言,断言可以用于验证传递给私有方法的参数。不过,断言不应应用于验证传递给公有方法的参数。因为不管是否启用了断言,公有方法都必须检查参数,不过既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。