常用框架

关于专业技能

熟练使用三大框架

MVC三层架构

M层负责DB逻辑的CRUD,架构师们开发出了大量的中间层JAR包,完成了DAO层,DO的封装,M层也完成了SERVICE层,完成了BO的封装,接口包的封装,系统使用了最常用的工厂、单例、FACACE等模式(直到现在,我面试人还是常常只会问这些基本的模式)。

V层的模板隔离,前端开发可以在这一层和后端开发一起修改界面(之后,更大规模的团队连这一层都可以再分离)。

C层完成输入输出的基本校验和检查然后调用后面的服务层功能或作转发。 简洁朴素的结构生命力是比较持久的。

说一下Spring的核心模块

  • Spring Core【核心容器】:核心容器提供了Spring的基本功能。核心容器的核心功能是用IOC容器来管理类的依赖关系。

  • Spring AOP【面向切面】:Spring的AOP模块提供了面向切面编程的支持。SpringAOP采用的是纯Java实现,采用基于代理的AOP实现方案,AOP代理由IOC容器负责生成、管理,依赖关系也一并由IOC容器管理。

  • Spring ORM【对象实体映射】:提供了与多个第三方持久层框架的良好整合。

  • Spring DAO【持久层模块】: Spring进一步简化DAO开发步骤,能以一致的方式使用数据库访问技术,用统一的方式调用事务管理,避免具体的实现侵入业务逻辑层的代码中。

  • Spring Context【应用上下文】:它是一个配置文件,为Spring提供上下文信息,提供了框架式的对象访问方法。

  • Spring Web【Web模块】:提供了基础的针对Web开发的集成特性。

  • Spring MVC【MVC模块】:提供了Web应用的MVC实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型。

(转发)forward与(重定向)redirect的区别

  • forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器。浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址。

  • redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的URL。

  • forward转发页面和转发到的页面可以共享request里面的数据。

  • redirect不能共享数据。

  • redirect不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。

  • forward只能在同一个Web应用程序内的资源之间转发请求。

  • forward是服务器内部的一种操作。

  • redirect是服务器通知客户端,让客户端重新发起请求。

  • forward一般用于用户登陆的时候根据角色转发到相应的模块。

  • redirect一般用于用户注销登陆时返回主页面和跳转到其它的网站等。

  • forward效率高。

  • redirect效率低。

Spring

  • Spring项目启动后的加载流程。
  • SpringMVC请求响应流程。

  • spring mvc的所有请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作。
  • DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
  • DispatcherServlet请求提交到目标Controller
  • Controller进行业务逻辑处理后,会返回一个ModelAndView
  • Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
  • 视图对象负责渲染返回给客户端

springmvc的核心是什么,请求的流程是怎么处理的,控制反转怎么实现的

核心:

控制反转和面向切面

请求处理流程:

1、首先用户发送请求到前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;

2、页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);

3、前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;

4、前端控制器再次收回控制权,将响应返回给用户。

控制反转如何实现:

我们每次使用spring框架都要配置xml文件,这个xml配置了bean的id和class。

spring中默认的bean为单实例模式,通过bean的class引用反射机制可以创建这个实例。

因此,spring框架通过反射替我们创建好了实例并且替我们维护他们。

A需要引用B类,spring框架就会通过xml把B实例的引用传给了A的成员变量。

spring里面的aop的原理是什么

这个有介绍,看这里:Spring的IOC原理动态代理

So 总体概括spring的启动过程:

1.首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;

2.其 次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时 contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始 化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是 XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的 context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取;

3.再 次,contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这里是DispatcherServlet,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请 求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE 先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个 parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方 法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是 mlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为 Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet 就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些 bean。

12,为什么要使用spring(即优点)?

1\. Spring能有效地组织你的中间层对象,不管你是否选择使用了EJB。如果你仅仅使用了Struts或其他为J2EE的 API特制的framework,Spring致力于解决剩下的问题。

2\. Spring能消除在许多工程中常见的对Singleton的过多使用。过多使用Singleton降低了系统的可测试性和面向对象的程度。

3\. 通过一种在不同应用程序和项目间一致的方法来处理配置文件,Spring能消除各种各样自定义格式的属性文件的需要。曾经对某个类要寻找的是哪个魔法般的 属性项或系统属性感到不解,为此不得不去读Javadoc甚至源编码?有了Spring,你仅仅需要看看类的JavaBean属性。Inversion ofControl的使用(在下面讨论)帮助完成了这种简化。

4.通过把对接口编程而不是对类编程的代价几乎减少到没有,Spring能够促进养成好的编程习惯。

5\. Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。

6\. 使用Spring构建的应用程序易于单元测试。

7.Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。

8\. Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适用于许多web应用。例如,Spring能使用AOP提供声明性事务管理而不通过EJB容器,如果你仅仅需要与单个数据库打交道,甚至不需要一个JTA实现。

9\. Spring为数据存取提供了一个一致的框架,不论是使用的是JDBC还是O/R mapping产品(如Hibernate)。

13,列举一下你知道的实现spring事务的几种方式

(1),编程式事务管理:需要手动编写代码,在实际开发中很少使用,

(2),基于TransactionProxyFactoryBean的声明式事务管理,需要为每个进行事务管理的类做相应配置

(3),基于AspectJ的XML的声明式事务管理,不需要改动类,在XML文件中配置好即可

(4),基于注解的声明式事务管理,配置简单,需要在业务层类中添加注解

14,谈谈spring事务的隔离级别和传播行为

隔离级别:

\- DEFAULT使用数据库默认的隔离级别

\- READ_UNCOMMITTED会出现脏读,不可重复读和幻影读问题

\- READ_COMMITTED会出现重复读和幻影读

\- REPEATABLE_READ会出现幻影读

\- SERIALIZABLE最安全,但是代价最大,性能影响极其严重

和传播行:

\- REQUIRED存在事务就融入该事务,不存在就创建事务

\- SUPPORTS存在事务就融入事务,不存在则不创建事务

\- MANDATORY存在事务则融入该事务,不存在,抛异常

\- REQUIRES_NEW总是创建新事务

\- NOT_SUPPORTED存在事务则挂起,一直执行非事务操作

\- NEVER总是执行非事务,如果当前存在事务则抛异常

\- NESTED嵌入式事务

15,什么是DI机制?

    依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。

    但在spring中 创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 

因此也称为依赖注入。

    spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 

    设置注入的优点:直观,自然 

    构造注入的优点:可以在构造器中决定依赖关系的顺序。 

16,什么是AOP?

面向切面编程(AOP)完善spring的依赖注入(DI),

面向切面编程在spring中主要表现为两个方面 :

1.面向切面编程提供声明式事务管理

2.spring支持用户自定义的切面

SSM优缺点、使用场景?

1. Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。 2. Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。 3. Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

Spring中bean的加载过程

1.获取配置文件资源

2.对获取的xml资源进行一定的处理检验

3.处理包装资源

4.解析处理包装过后的资源

5.加载提取bean并注册(添加到beanDefinitionMap中)

ClassPathXmlApplicationContext实现beanFactory接口,是一个具体的实例化工厂。服务器启动时,解析xml配置文件

将对应文件中每个bean的id作为key,属性封装到beandefinition作为value,封装到一个ConCurrentHashMap容器A中。

同时,还有一个ConCurrentHashMap容器B存储bean的实例化对象,默认是空。当有一个请求时,首先去B中,查找。如果

B容器没有,则访问A容器,如果是单例,则创建之后,仍要保存到B中,下次可以使用。如果是非单例的,则直接创建,并不

在B中保存副本。

说一下spring中Bean的作用域

singleton:

Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。Singleton作用域是Spring中的缺省作用域。

prototype:

每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态,而singleton全局只有一个对象。

request:

在一次Http请求中,容器会返回该Bean的同一实例。而对不同的Http请求则会产生新的Bean,而且该bean仅在当前Http Request内有效。

session:

在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效。

global Session:

在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。

说一下spring中Bean的生命周期

  • 实例化一个Bean,也就是我们通常说的new。
  • 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入。
  • 如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID。
  • 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)。
  • 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文。
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术。
  • 如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法。
  • 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法。
  • 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

10、请解释Spring Bean的生命周期?

Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。

Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。

  1. 初始化之后调用的回调方法。
  2. 销毁之前调用的回调方法。

Spring框架提供了以下四种方式来管理bean的生命周期事件:

  • InitializingBean和DisposableBean回调接口
  • 针对特殊行为的其他Aware接口
  • Bean配置文件中的Custom init()方法和destroy()方法
  • @PostConstruct和@PreDestroy注解方式

对Spring中依赖注入两种方式的认识

两种注入方式为:构造方法注入和设值注入

  1. 设值注入与传统的JavaBean的写法更相似,程序员更容易理解、接受,通过setter方式设定依赖关系显得更加直观、明显;
  2. 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而会产生浪费。而使用设置注入,则避免这下问题;
  3. 在某些属性可选的情况下,多参数的构造器更加笨拙,官方更鼓励使用设值注入。
  4. 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。
  5. 对于依赖关系无须变化的Bean,构造注入更有用处,因为没有setter方法,所有的依赖关系全部在构造器内设定,因此,不用担心后续代码对依赖关系的破坏。
  6. 构造注入使依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
  7. 设值注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。
  8. 建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用set注入。

Spring框架中都用到了哪些设计模式?

  • 代理模式:在AOP和remoting中被用的比较多。
  • 单例模式:在spring配置文件中定义的bean默认为单例模式。
  • 模板方法模式:用来解决代码重复的问题。
  • 前端控制器模式:Spring提供了DispatcherServlet来对请求进行分发。
  • 依赖注入模式:贯穿于BeanFactory / ApplicationContext接口的核心理念。
  • 工厂模式:BeanFactory用来创建对象的实例。

BeanFactory 和ApplicationContext的区别

BeanFactory和ApplicationContext都是接口,并且ApplicationContext是BeanFactory的子接口。

BeanFactory是Spring中最底层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能。而ApplicationContext是Spring的一个更高级的容器,提供了更多的有用的功能。

ApplicationContext提供的额外的功能:国际化的功能、消息发送、响应机制、统一加载资源的功能、强大的事件机制、对Web应用的支持等等。

加载方式的区别:BeanFactory采用的是延迟加载的形式来注入Bean;ApplicationContext则相反的,它是在Ioc启动时就一次性创建所有的Bean,好处是可以马上发现Spring配置文件中的错误,坏处是造成浪费。

  • Spring事务什么时候会失效?
  • 手写一段单例模式?
  • sychornized和volatile关键字
  • 三个线程T1里输出t1,T2输出t2,T3输出t3,如何保证控制台顺序打印t1,t2,t3?join
  • 二分查找法的算法实现(不会,直接跳过了)
  1. mybatis怎么防止SQL注入#{}

Mybatis

  1. 简单介绍下你对mybatis的理解?

1. mybatis配置 2. SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。 3. mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。 4. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂 5. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。 6. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。 7. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。 8. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。 9. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

14)mybatis如何处理结果集:反射,建议看看源码;

Mybatis和Hibernate的区别(优缺点)

Hibernate工作原理及为什么要使用Hibernate?

工作原理:

1.读取并解析配置文件 

2.读取并解析映射信息,创建SessionFactory

3.打开Session 

4.创建事务Transation 

5.持久化操作

6.提交事务 

7.关闭Session 

8.关闭SesstionFactory

为什么要使用Hibernate(即它的优点):

1\. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。 

2\. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作 

3\. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 

4\. hibernate映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

2, Hibernate中get和load方法的区别

    hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;

    hibernate对于get方法,hibernate一定要获取到真实的数据,否则返回null。

具体介绍:

    1\. 对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。

    2.  load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true)。

分情况讨论:

    (1)若为true,则首先在Session缓存中查找,看看该id对应的对象是否存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象(除获取OID以外)的时候,再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。

    (2)若为false,就跟get方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。

3,Hibernate是如何延迟加载?

   Hibernate3 提供了属性的延迟加载功能。当Hibernate在查询数据的时候,数据并没有存在于内存之中,而是当程序真正对数据的操作时,对象才存在于内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 

4,Hibernate中怎样实现类之间的关系?

    类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们在程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many进行操作。

5,Hibernate中的update()和saveOrUpdate()的区别?

saveOrUpdate():

1,如果对象已经在本session中持久化了,不做任何事

2,如果另一个与本session关联的对象拥有相同的持久化标识(identifier),抛出一个异常

3,如果对象没有持久化标识(identifier)属性,对其调用save()

4,如果对象的持久标识(identifier)表明其是一个新实例化的对象,对其调用save()

5,如果对象是附带版本信息的(通过<version>或 <timestamp>)并且版本属性的值表明其是一个新实例化的对象,调用save()。否则update() 这个对象。

update() :

    是将一个游离状态的实体对象直接更新。

6,说说Hibernate的缓存机制。

1. 一级缓存:内部缓存存在Hibernate中,属于应用事物级缓存。

2. 二级缓存:应用级缓存、 分布式缓存。

使用场景:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据

3.引入第三方缓存(如ehcache等)。

7,如何优化Hibernate?

1.使用双向一对多关联,不使用单向一对多

2.灵活使用单向一对多关联

3.不用一对一,用多对一取代

4.配置对象缓存,不使用集合缓存

5.一对多集合使用Bag,多对多集合使用Set

6. 继承类使用显式多态

7. 表字段要少,表关联不要怕多,有二级缓存撑腰

8,谈谈hibernate的延迟加载和openSessionInView

    延迟加载要在session范围内,用到的时候再加载;

    opensessioninview是在web层写了一个filter来打开和关闭session,这样就表示在一次request过程中session一直开着,保证了延迟加载在session中的这个前提。

9,简要阐述struts2的工作流程

1、客户端浏览器发出HTTP请求。

2、根据web.xml配置,该请求被FilterDispatcher接收。

3、根据struts.xml配置,找到需要调用的Action类和方法,并通过IoC方式,将值注入给Aciton。

4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。

5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。

6、返回HTTP响应到客户端浏览器。

10,说下Struts的设计模式

MVC模式

1,web应用程序启动时就会加载并初始化ActionServlet;

2,用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数 据;

3,ActionServlet根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法;

4,Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对 象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件;

5,ActionForward对象指定的jsp生成动 态的网页,返回给客户。

11,Struts的优缺点

优点:

1\. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.

2\. 有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率。另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。

3\. 页面导航.页面导航将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。

4\. 提供Exception处理机制 .

5\. 数据库链接池管理

6\. 支持I18N

缺点:

1\. 转到展示层时,需要配置forward,每一次转到展示层,相信大多数都是直接转到jsp,而涉及到转向, 需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器,如果业务变更复杂频繁的系统,这样的操作简单不可想象。现在就是这样,几十上百个人同时在线使用我们的系统,大家可以想象一下,我的烦恼有多大。

2\. Struts 的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。

3\. 测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。

4\. 类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。

5\. 对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest 和ServletResponse,所有它摆脱不了Servlet容器。

6\. 前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。

7\. 对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。

8\. 对Action 执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。

9\. 对事件支持不够. 在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能 对应一个事件,struts这种事件方式称为applicationevent,application event和component event相比是一种粗粒度的事件。

jetty、Activiti工作流引擎(WorkFlow),JMS、熟练掌握Java编程和设计、Web Service和XML、RESTful、JSON、JSP、Servlet、JSTL、JDBC、JavaScript、Ajax、JUnit等相关技术;

于主流的开源框架(SSH、SSM、SpringMVC、Spring、Jfinal等)quartz HttpClient/Webservice

Dubbo源码使用了哪些设计模式?

工厂模式:

ExtenstionLoader.getExtenstionLoader(Protocol.class).getAdaptiveExtenstion()

装饰器模式+责任链:

以provider的调用链为例,具体调用链代码是在protocolFilterWrapper的buildInvokeChain完成的,将注解中含有group=provider的Filter实现。

调用顺序:

  1. EchoFilter
  2. ClassLoaderFilter
  3. GenericFilter
  4. ContextFilter
  5. ExceptionFilter
  6. TimeoutFilter
  7. MonitorFilter
  8. TraceFilter

装饰器模式和责任链混合使用,Echo是回声测试请求,ClassLoaderFilter则只是在其主功能上添加了功能。

观察者模式:

provider启动时需要与注册中心交互,先注册自己的服务,再订阅自己的服务,订阅时采用了观察者模式,注册中心每5s定时检查是否有服务更新,有更新则向服务提供者发送1个notify消息后即可运行NotifyListener的notity方法,执行监听器方法。

动态代理模式:

扩展JDK的ExtensionLoaderdeAdaptive实现,根据调用阶段动态参数决定调用哪个类,生成代理类的代码是ExtensionLoader的createAdaptiveExtenstionClassLoader方法

数据库

1、使用mysq1索引都有哪些原则? ?索引什么数据结构? 3+tree 和B tree 什么区别?

2、mysq1有哪些存储引擎啊?都有啥区别? 要详细!

3、设计高并发系统数据库层面该怎么设计??数据库锁有哪些类型?如何实现呀?

4、数据库事务有哪些?

分库分表

1、如何设计可以动态扩容缩容的分库分表方案?

2、用过哪些分库分表中间件,有啥优点和缺点?讲一下你了解的分库分表中间件的底层实现原理?

3、我现在有一个未分库分表的系统,以后系统需分库分表,如何设计,让未分库分表的系统动态切换到分库分表的系统上???TCC? 那若出现网络原因,网络连不通怎么办啊???

4、分布式事务知道吗? 你们怎么解决的?

5、为什么要分库分表啊???

6、分布式寻址方式都有哪些算法知道一致性hash吗?手写一下java实现代码??你若userId取摸分片,那我要查一段连续时间里的数据怎么办???

7、如何解决分库分表主键问题有什么实现方案??

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python的常用框架有很多,其中一些常见的包括Django、Flask、Pyramid、Tornado和Web2py等。这些框架提供了不同的功能和特点,适用于不同类型的应用开发。例如,Django是一个全功能的Web框架,提供了许多内置的功能和工具,适用于构建复杂的Web应用程序。Flask是一个轻量级的Web框架,更加灵活和简单,适用于小型项目或原型开发。Pyramid是一个通用的Web框架,可以用于构建各种类型的应用程序。Tornado是一个异步的Web框架,适用于处理高并发的应用。而Web2py是一个全栈式的Web框架,提供了一体化的解决方案,适用于快速开发和部署应用。这些框架都有自己的优势和适用场景,开发者可以根据项目需求选择合适的框架进行开发。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [15 个常用的python 开源框架](https://blog.csdn.net/qq_23183809/article/details/120485560)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [undefined](undefined)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值