框架解析

来源:互联网 发布:淘宝买手机怎么看真假 编辑:程序博客网 时间:2024/05/22 23:57

康世界上并没有完美的程序,但我们并不因此沮丧,因为写程序本来就是一个不断追求完美的过程。
[原]Struts的一些总结
1、Struts2与Struts1的区别

Action类

Struts1的Action必须继承
Struts2的Acton可以不继承
线程

Struts1单例的,存在线程安全问题,如果用actionform的话,ActionForm是多例的,所以可以保证线程安全
Struts2多例的,没有线程安全问题
(ps:struts2只能是多例的,struts1将action交给spring管理可以是多例的)
ActionForm

Struts1收集数据使用ActionForm,ActionForm需要继承。复用率低。
Struts2可以不用ActionForm,之间让Action来收集数据,采用ModelDriven支持Struts1的ActionForm方式。
表达式语言方面

Struts1中使用jstl
Struts2中使用ognl
类型转换

Struts1中对ActionForm的类型转换采用commons-beanutils工具,一个转换器对所有ActionForm起作用,不能针对单个配置。
Struts2使用OGNL进行类型转换,可以针对某个类型进行配置。
校验

Struts1采用覆盖ActionForm中的validate方法或采用验证框架commons validator验证
Struts2支持覆盖validate来完成验证,也支持验证框架xWork来验证
Action执行控制

Struts1固定不变
Struts2通过拦截器,可以改变执行流程,灵活配置
2、Struts1的流程

浏览器请求到ActionServlet类,该类将响应请求并进行分发到Action,Action调用Model。将请求返回给ActionServlet,ActionServlet将请求回的数据forward到jsp,并将jsp返回给浏览器。

3、Struts2的流程

客户端浏览器发起请求,请求先经过一系列的Filter(所以filter的生命周期)最先到达ActionContextCleanUp,再到其他的过滤器,之后到StrutsPrepareAndExecuteFilter过滤器,接着StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请求需要调用的Action,如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求交给ActionProxy处理;Actionproxy通过Configuration Manager询问框架的配置文件,找到需要调用的action类。ActionProxy创建一个ActionInvocation实例。ActionInvocation实例使用命名模式来调用,在调用Action的过程前后都涉及到相关拦截器的调用,默认是18个拦截器。一旦Action执行完毕,ActionInvocation负责根据struts.xml中配置找到对应的返回结果。表示过程中可以使用struts2标签,需要Actionmapper。

4、Filter、Servlet、Interceptor、Listener区别?

项目
Servlet
Listener
Filter
Interceptor
包名
javax.servlet.http.HttpServlet
javax.servlet.ServletContextListener
javax.servlet.Filter
com.opensymphony.xwork2.interceptor.AbstractInterceptor
功能
生成响应内容并且将其传给服务器
做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。基于函数回调
基于java反射机制。面向切面编程。
生命周期
由容器控制,可以配置。无配置时默认在第一次调用前加载,容器关闭时销毁,当容器做内存回收时也可能被销毁。不能离开web容器
随web容器启动,只初始化一次,不能离开web容器。
Web容器启动时启动,初始化一次,不能离开web容器。在容器初始化时被调用一次
加载struts.xml后,初始化相应拦截器,服务器停止销毁拦截器。不依赖web容器,可以多次调用
配置位置
Web.xml中3.0后开始支持注解
Web.xml中
Web.xml中
Struts配置文件中
作用对象
url
对象,如session的创建,session.setAttribute发生
url、action几乎所有对象
Action
Web.xml加载顺序:context- param -> listener ->filter -> servlet.
执行流程图:
Servlet:

Filter:

Listener:

Interceptor:

5、struts.xml文件什么时候加载与特性

StrutsPreparedAndExecuteFilter的init方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。Struts2读取到struts.xml的内容后,是将内容封装进javabean对象然后存放在内存中,以后用户每次请求处理将使用内存中的数据,而不是每次都请求读取struts.xml文件。
6、struts2框架的核心过滤器?作用?

StrutsPrepareAndExecuteFilter。作用:拦截url-pattern指定的所有用户请求,当请求到达时,该filter会过滤用户请求。
7、值栈ValueStack的原理和生命周期?

保存在request域中和request的生命周期一样。每个action都有一个对应的值栈,值栈存放的数据类型是该action的实例,以及该action中的实例变量,action默认保存在栈顶。ValueStack本质上是ArrayList。
8、OGNL与JSTL与EL表达式?

Jstl:是jsp标签;ognl与el类似都是表达式语言。El与jstl联用,jstl用来取值,el用来展示。
产品
Struts2标签
Ognl
Jstl
El
使用方式
引入:<%@ taglib uri=”/struts-tags” prefix=”s”%>
使用:好多种取值方式
对象图形化导航语言,要结合struts标签使用。符号:#、<{}
Java内存简介
一:Java技术体系模块图

二:JVM内存区域模型

1.方法区
也称”永久代”、“非堆”, 它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。默认最小值为16MB,最大值为64MB,可以通过-XX:PermSize和 -XX:MaxPermSize 参数限制方法区的大小。
运行时常量池:是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种符号引用,这部分内容将在类加载后放到方法区的运行时常量池中。
回到顶部
2.虚拟机栈
描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个“栈帧”用于存储局部变量表(包括参数)、操作栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。声明周期与线程相同,是线程私有的。
局部变量表存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(引用指针,并非对象本身),其中64位长度的long和double类型的数据会占用2个局部变量的空间,其余数据类型只占1个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量是完全确定的,在运行期间栈帧不会改变局部 变量表的大小空间。
回到顶部
3.本地方法栈
与虚拟机栈基本类似,区别在于虚拟机栈为虚拟机执行的java方法服务,而本地方法栈则是为Native方法服务。
4.堆
也叫做java堆、GC堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域,在JVM启动时创建。该内存区域存放了对象实例及数组(所有new的对象)。其大小通过-Xms(最小值)和-Xmx(最大值)参数设置,-Xms为JVM启动时申请的最小内存,默认为操作系统物理内存的1/64但小于1G,-Xmx为JVM可申请的最大内存,默认为物理内存的1/4但小于1G,默认当空余堆内存小于40%时,JVM会增大Heap到-Xmx指定的大小,可通过-XX:MinHeapFreeRation=来指定这个比列;当空余堆内存大于70%时,JVM会减小heap的大小到-Xms指定的大小,可通过XX:MaxHeapFreeRation=来指定这个比列,对于运行系统,为避免在运行时频繁调整Heap的大小,通常-Xms与-Xmx的值设成一样。
由于现在收集器都是采用分代收集算法,堆被划分为新生代和老年代。新生代主要存储新创建的对象和尚未进入老年代的对象。老年代存储经过多次新生代GC(MinorGC)任然存活的对象。
新生代:
程序新创建的对象都是从新生代分配内存,新生代由EdenSpace和两块相同大小的SurvivorSpace(通常又称S0和S1或From和To)构成,可通过-Xmn参数来指定新生代的大小,也可以通过-XX:SurvivorRation来调整EdenSpace及Survivor Space的大小。
老年代:
用于存放经过多次新生代GC任然存活的对象,例如缓存对象,新建的对象也有可能直接进入老年代,主要有两种情况:①.大对象,可通过启动参数设置-XX:PretenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大时就不在新生代分配,而是直接在老年代分配。②.大的数组对象,切数组中无引用外部对象。
老年代所占的内存大小为-Xmx对应的值减去-Xmn对应的值。
5.程序计数器
它的作用是当前线程所执行的字节码的行号指示器,在虚拟机的模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、异常处理、线程恢复等基础功能都需要依赖计数器完成。
三:直接内存
直接内存并不是虚拟机内存的一部分,也不是Java虚拟机规范中定义的内存区域。jdk1.4中新加入的NIO,引入了通道与缓冲区的IO方式,它可以调用Native方法直接分配堆外内存,这个堆外内存就是本机内存,不会影响到堆内存的大小。

作者:kanglix1an 发表于2015/8/31 22:35:16 原文链接
阅读:687 评论:6 查看评论
[原]J2EE 13个规范概览
J2EE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持。下面对J2EE中的13种进行简单的描述:

  1. JDBC(Java Database Connectivity):
    JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDCB对数据库的访问也具有平台无关性。
    简单说JDBC可以干三件事:与数据库连接、发送操作数据库的语句、处理结果;

  2. JNDI(Java Name and Directory Interface):
    java命名和目录接口,是一组在应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP,本地文件系统,或中的对象。
    JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI SPI的实现,有管理者将JNDI映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。
    JNDI是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。
    JNDI可以访问的现有目录及服务:DNS、XNam、Novell目录服务、LDAP、CORBA对象服务、文件系统、注册表、RMI、DSML、NIS;

3.EJB(Enterprise JavaBean):
EJB是服务器端的组件模型,设计目标与核心应用是部署分布式应用程序。EJB是J2EE的一部分,定义了一个用于开发基于组件的企业多重应用程序标准,是Java核心代码,分别是会话Bean(Session Bean),实体Bean(Entity Bean),消息驱动Bean(MessageDriven Bean)。
SessionBean用于实现业务逻辑,可以是有状态的也可以是无状态的,每当客户端请求时容器会选择一个SessionBean来为客户端服务。Session Bean可以直接访问数据库,但更多时候它会通过Entity Bean实现数据访问。
Entity Bean是域模型对象,用于实现OR映射,负责将数据库中的表记录映射为内存中的Entity对象,事实上,创建一个EntityBean对象相当于新建一条记录,删除一个Entity Bean会同时从数据库删除对应记录,修改一个Entity Bean时容器会自动将Entity Bean的状态和数据库同步。
MessageDriven Bean是EJB2.0中引入的新的企业Bean,基于JMS消息,只能就收客户端发送的JMS消息然后处理。MDB实际上是一个异步的无状态SessionBean,客户端调用MDB后无需等待,立刻返回,MDB将异步处理客户请求。
EJB实际上是J2EE中的一套规范,并且规定了一系列的API用来实现把EJB概念转换成EJB产品。

       EJB从技术上而言不是一种“产品”EJB是一种描述了构建应用组件要解决的标准:

可拓展(Scalable)
分布式(Distributed)
事务处理(Transactional)
数据存储(Persistent)
安全性(Secure)

4.RMI(Remote Method Invoke):
RMI是java的一组拥护开发分布式应用程序的API。RMI使用java语言接口定义了远程对象,它集合了java序列化和Java远程方法协议(Java Remote Method Protocol)。使原先的程序在同一操作系统的方法调用,变成了不同操作系统之间程序的方法调用,由于J2EE是分布式成习惯平台,它以RMI机制实现程序组件在不同操作系统之间的通信。
RMI目前使用java远程信息交换协议JRMP(java remotemessaging protocol)进行通信。Jrmp是专门为java的远程对象制定的协议。RMI允许使用java编写分布式对象。

5.Java IDL/CORBA:
在Java IDL的支持下,开发人员可以将Java和CORBA集成在一起。他们可以创建Java对象并使之可在CORBAORB中展开,或者他们还可以创建Java类并作为和其它ORB一起展开的CORBA对象的客户。后一种方法提供了另外一种途径,通过它Java可以被用于将你的新的应用和旧的系统相集成。

6.JSP(Java Server Pages):
JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理,然后将生成的HTML页面返回给客户端的浏览器。
是一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件中插入Java程序段和JSP标记,从而形成JSP文件,后缀名为JSP。Java程序段可以操纵数据库、重新定向网页以及发送E-mail等,实现建立动态网站所需要的功能。所有程序操作都在服务器端执行,网络上传送给客户端的仅是得到的结果,这样大大降低了对客户浏览器的要求,即使客户浏览器不支持java,也可以访问JSP网页。
JSP根本是一个简化的Servlet设计,实现了html语法中的java扩张。在服务器端执行,返回给客户端的通常是一个纯HTML文本,因此对客户端要求很低。服务器在遇到访问JSP网页的请求时,首先执行其中的程序段,然后将执行结果连同JSP文件中的HTML代码一起返回给客户端。通常JSP页面很少进行数据处理,只用来实现网页的静态化界面,只是用来提取数据,不会进行业务处理。JSP主要目的是将表示逻辑从Servlet中分离出来。

7.Java Servlet:
Servlet是一种小型的Java程序,它扩展了Web服务器的功能。作为一种服务器端的应用,当被请求时开始执行,这和CGI Perl脚本很相似。Servlet提供的功能大多与JSP类似,不过实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码,而s全部由Java写成并且生成HTML。

8.XML(Extensible Markup Language):
XML是一种可以用来定义其它的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是相互独立的,但是,它和Java具有的相同目标正是平台独立性。通过将Java和XML的组合,您可以得到一个完美的具有平台独立性的解决方案。

9.JMS(Java Message Service):
JMS是用于和面向消息的相互通信的(API)。它既支持的域,有支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。

10.JTA(Java Transaction Architecture):
JTA定义了一种标准的API,应用系统由此可以访问各种事务监控。JTA允许应用程序执行分布式事务处理—在两个或多个网络计算机资源上访问并且更新数据。Jdbc驱动程序的jta支持极大地增强了数据访问能力。JTA事务比JDBC事务强大很多,一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。

11.JTS(Java Transaction Service):
JTS是CORBA OTS事务监控的基本的实现。JTS规定了器的实现方式。该器是在高层支持Java Transaction API (JTA)规范,并且在较底层实现OMG OTS specification的Java映像。JTS事务管理器为独立的应用以及通信提供了事务服务。

12.JavaMail:
JavaMail是用于存取的API,它提供了一套的。不仅支持SMTP服务器,也支持IMAP服务器。

13.JAF(JavaBeans Activation Framework):
一个专用的数据处理框架,用于封装数据,并为应用程序提供访问和操作数据的接口,主要作用在于让java应用程序知道如何对一个数据源进行查看、编辑和打印操作。JavaMail利用JAF来处理MIME编码的邮件附件。MIME的可以被转换成Java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF。
作者:kanglix1an 发表于2015/8/31 22:27:48 原文链接
阅读:804 评论:4 查看评论
[原]Redis
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis优势

(1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。

(2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。

(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。

(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。

简单使用

首先启动Redis服务。

测试代码:

public class RedisTest {

public static void main(String[] args){    //连接Redis服务器    Jedis jedis=new Jedis("localhost");    System.out.println("connection to server successfully");    //测试string类型    jedis.set("kanglixian", "xiaokang");    System.out.println("Server is running:"+jedis.get("kanglixian"));    //测试list类型    jedis.lpush("listIn", "FirstIn");    jedis.lpush("listIn", "SecondIn");    jedis.lpush("listIn", "ThirdIn");    List<String> list=jedis.lrange("listIn", 0, 5);    for(int i=0;i<list.size();i++){        System.out.println("第"+i+"个值:"+list.get(i));    }    //取所有的key    Set<String> set=jedis.keys("*");    Iterator iterator=set.iterator();    while(iterator.hasNext()){        System.out.println("值:"+iterator.next());    }}

}

控制台结果输出:

与spring结合使用

第一种方法:

目录结构如下:

UserDaoImpl代码:

public class UserDaoImpl implements UserDao{

@Autowiredprotected RedisTemplate<Serializable, Serializable> redisTemplate;public void saveUser(final User user) {    redisTemplate.execute(new RedisCallback<Object>() {        public Object doInRedis(RedisConnection connection) throws DataAccessException {            connection.set(redisTemplate.getStringSerializer().serialize("user.uid." + user.getId()),                           redisTemplate.getStringSerializer().serialize(user.getName()));            return null;        }    });}public User getUser(final long id) {    return redisTemplate.execute(new RedisCallback<User>() {        public User doInRedis(RedisConnection connection) throws DataAccessException {            byte[] key = redisTemplate.getStringSerializer().serialize("user.uid." + id);            if (connection.exists(key)) {                byte[] value = connection.get(key);                String name = redisTemplate.getStringSerializer().deserialize(value);                User user = new User();                user.setName(name);                user.setId(id);                return user;            }            return null;        }    });}

}

spring配置文件:applicationContext.xml

1 0
原创粉丝点击