第一部分 Java基础
第二部分 Java进阶

Java spring面试题及答案(1~11题)

1、SpringMVC的工作原理?

● 用户向服务器发送请求,请求被springMVC前端控制器DispatchServlet捕获;

● DispatcherServle对请求URL进行解析,得到请求资源标识符(URL),然后根据该URL调用HandlerMapping将请求映射到处理器HandlerExcutionChain;

● DispatchServlet根据获得Handler选择一个合适的HandlerAdapter适配器处理;

● Handler对数据处理完成以后将返回一个ModelAndView对象给DisPatchServlet;

● Handler返回的ModelAndView只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver试图解析器将逻辑视图转化为真正的视图View;

● DispatcherServle通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端;

2、SpringMVC常用注解都有哪些?

● @RequestMapping用于请求url映射。

● @RequestBody注解实现接收http请求的json数据,将json数据转换为java对象。

● @ResponseBody注解实现将controller方法返回对象转化为json响应给客户。

3、如何开启注解处理器和适配器?

我们在项目中一般会在springmvc.xml中通过开启<mvc:annotation-driven>来实现注解处理器和适配器的开启。

4、如何解决get和post乱码问题?

解决post请求乱码:我们可以在web.xml里边配置一个CharacterEncodingFilter过滤器。设置为utf-8.解决get请求的乱码:有两种方法。对于get请求中文参数出现乱码解决方法有两个:

● 修改tomcat配置文件添加编码与工程编码一致。

● 另 外 一 种 方 法 对 参 数 进 行 重 新 编 码 String userName = new String(request.getParameter(“userName”).getBytes(“ISO8859-1”),“utf-8”);

5、谈谈你对Spring的理解?

Spring是一个开源框架,为简化企业级应用开发而生。Spring可以是使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。

● Spring容器的主要核心是:

控制反转(IOC),传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象。而在spring开发模式中,spring容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring提供的对象就可以了,这是控制反转的思想。

依赖注入(DI),spring使用JavaBean对象的set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。

面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP底层是动态代理,如果是接口采用JDK动态代理,如果是类采用CGLIB方式实现动态代理

6、Spring中的设计模式有哪些?

● 单例模式——spring中两种代理方式,若目标对象实现了若干接口,spring使用jdk的java.lang.reflect.Proxy类代理。若目标兑现没有实现任何接口,spring使用CGLIB库生成目标类的子类。单例模式——在spring的配置文件中设置bean默认为单例模式。

● 模板方式模式——用来解决代码重复的问题。比如:RestTemplate、JmsTemplate、JpaTemplate

● 前端控制器模式——spring提供了前端控制器DispatherServlet来对请求进行分发。

● 试图帮助(viewhelper)——spring提供了一系列的JSP标签,高效宏来帮助将分散的代码整合在试图中。

● 依赖注入——贯穿于BeanFactory/ApplacationContext接口的核心理念。

● 工厂模式——在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用同一个接口来指向新创建的对象。Spring中使用beanFactory来创建对象的实例。

7、Spring的常用注解?

Spring在2.5版本以后开始支持注解的方式来配置依赖注入。可以用注解的方式来代替xml中bean的描述。注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。

注解装配在spring中默认是关闭的。所以需要在spring的核心配置文件中配置一下才能使用基于注解的装配模式。配置方式如下:<context:annotation-config/>

● 常用的注解:

@Required:该注解应用于设值方法。

@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。

@Qualifier:该注解和@Autowired搭配使用,用于消除特定bean自动装配的歧义。

8、简单介绍一下spring bean的生命周期?

● bean定义:在配置文件里面用<bean></bean>来进行定义。

● bean初始化:有两种方式初始化:

1、在配置文件中通过指定init-method属性来完成。

2、实现org.springframwork.beans.factory.InitializingBean接口。

● bean调用:有三种方式可以得到bean实例,并进行调用

● bean销毁:销毁有两种方式:

1、使用配置文件指定的destroy-method属性。

2、实现org.springframwork.bean.factory.DisposeableBean。

9、Spring结构图了解吗?

● 核心容器:包括Core、Beans、Context、EL模块。

1、Core模块:封装了框架依赖的最底层部分,包括资源访问、类型转换及一些常用工具类。

2、Beans模块:提供了框架的基础部分,包括反转控制和依赖注入。其中BeanFactory是容器核心,本质是“工厂设计模式”的实现,而且无需编程实现“单例设计模式”,单例完全由容器控制,而且提倡面向接口编程,而非面向实现编程;所有应用程序对象及对象间关系由框架管理,从而真正把你从程序逻辑中把维护对象之间的依赖关系提取出来,所有这些依赖关系都由BeanFactory来维护。

3、Context模块:以Core和Beans为基础,集成Beans模块功能并添加资源绑定、数据验证、国际化、JavaEE支持、容器生命周期、事件传播等;核心接口是ApplicationContext。

4、EL模块:提供强大的表达式语言支持,支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从Spring容器获取Bean,它也支持列表投影、选择和一般的列表聚合等。

● AOP、Aspects模块:

1、AOP模块:SpringAOP模块提供了符合AOPAlliance规范的面向方面的编程(aspect-orientedprogramming)实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中;这样各专其职,降低业务逻辑和通用功能的耦合。

2、Aspects模块:提供了对AspectJ的集成,AspectJ提供了比SpringASP更强大的功能。数据访问/集成模块:该模块包括了JDBC、ORM、OXM、JMS和事务管理。

3、事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事务管理。

4、JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。

5、ORM模块:提供与流行的“对象-关系”映射框架的无缝集成,包括Hibernate、JPA、MyBatis等。而且可以使用Spring事务管理,无需额外控制事务。

6、OXM模块:提供了一个对Object/XML映射实现,将java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。

7、JMS模块:用于JMS(JavaMessagingService),提供一套“消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

8、Web/Remoting模块:Web/Remoting模块包含了Web、Web-Servlet、Web-Struts、Web-Porlet模块。

9、Web模块:提供了基础的web功能。例如多文件上传、集成IoC容器、远程过程访问(RMI、Hessian、Burlap)以及WebService支持,并提供一个RestTemplate类来提供方便的Restfulservices访问。

10、Web-Servlet模块:提供了一个SpringMVCWeb框架实现。SpringMVC框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与Spring其他技术协作。

11、Web-Struts模块:提供了与Struts无缝集成,Struts1.x和Struts2.x都支持

12、Test模块:Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能。

10、Spring能帮我们做什么?

● Spring能帮我们根据配置文件创建及组装对象之间的依赖关系。

● Spring根据配置文件来进行创建及组装对象间依赖关系,只需要改配置文件即可

● Spring面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。

● Spring面向切面编程能提供一种更好的方式来完成,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑。

● Spring能非常简单的帮我们管理数据库事务。

● 采用Spring,我们只需获取连接,执行SQL,其他事物相关的都交给Spring来管理了。

● Spring还能与第三方数据库访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板,来方便数据库访问。

● Spring还能与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套SpringMVC框架,来方便web层搭建。

● Spring能方便的与JavaEE(如JavaMail、任务调度)整合,与更多技术整合(比如缓存框架)。

11、请描述一下Spring的事务?

声明式事务管理的定义:用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。

基于TransactionInterceptor的声明式事务管理:两个次要的属性:transactionManager,用来指定一个事务治理器,并将具体事务相关的操作请托给它;其他一个是Properties类型的transactionAttributes属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符,而值就是表现呼应方法的所运用的事务属性。

<beans>
    ......
    <bean id="transactionInterceptor"
          class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    <bean id="bankServiceTarget"
          class="footmark.spring.core.tx.declare.origin.BankServiceImpl">
        <property name="bankDao" ref="bankDao"/>
    </bean>
    <bean id="bankService"
          class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="bankServiceTarget"/>
        <property name="interceptorNames">
            <list>
                <idref bean="transactionInterceptor"/>
            </list>
        </property>
    </bean>
</beans>

基于 TransactionProxyFactoryBean 的声明式事务管理:设置配置文件与先前比照简化了许多。我们把这类设置配置文件格式称为 Spring 经典的声明式事务治理。 

<beans>
    ......
    <bean id="bankServiceTarget"
          class="footmark.spring.core.tx.declare.classic.BankServiceImpl">
        <property name="bankDao" ref="bankDao"/>
    </bean>
    <bean id="bankService"
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="target" ref="bankServiceTarget"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
</beans>

基于  <tx>   命名空间的声明式事务治理:在前两种方法的基础上,Spring 2.x  引入了  <tx>  命名空间, 连络行使 <aop> 命名空间,带给开发人员设置配备声明式事务的全新体验。

<beans>
    ......
    <bean id="bankService"
          class="footmark.spring.core.tx.declare.namespace.BankServiceImpl">
        <property name="bankDao" ref="bankDao"/>
    </bean>
    <tx:advice id="bankAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="bankPointcut" expression="execution(* *.transfer(..))"/>
        <aop:advisor advice-ref="bankAdvice" pointcut-ref="bankPointcut"/>
    </aop:config>
    ......
</beans>

基于  @Transactional  的声明式事务管理:Spring  2.x  还引入了基于  Annotation  的体式格式,具体次要触及@Transactional   标注。@Transactional   可以浸染于接口、接口方法、类和类方法上。算作用于类上时,该类的一切public 方法将都具有该类型的事务属性。

@Transactional(propagation = Propagation.REQUIRED)
public boolean transfer(Long fromId, Long toId, double amount) {
    return bankDao.transfer(fromId, toId, amount);
}

编程式事务管理的定义:在代码中显式挪用 beginTransaction()、commit()、rollback()等事务治理相关的方法, 这就是编程式事务管理。Spring 对事物的编程式管理有基于底层 API 的编程式管理和基于 TransactionTemplate 的编程式事务管理两种方式。

基于底层 API 的编程式管理:凭证 PlatformTransactionManager 、 TransactionDefinition 和TransactionStatus 三个焦点接口,来实现编程式事务管理。

public class BankServiceImpl implements BankService {
    private BanckDao bankDao;
    private TransactionDefinition txDefinition;
    private PlatformTransactionManager txManager;

    public boolean transfer(Long fromId, Long toId, double amount) {
        TransactionStatus txStatus = txManager.getTransaction(txDefinition);
        boolean result = false;
        try {
            result = bankDao.transfer(fromId, toId, amount);
            txManager.commit(txStatus);
        } catch (Exception e) {
            result = false;
            txManager.rollback(txStatus);
            System.out.println("Transfer Error!");
        }
        return result;
    }
}

基于 TransactionTemplate  的编程式事务管理:为了不损坏代码原有的条理性,避免出现每一个方法中都包括相同的启动事物、提交、回滚事物样板代码的现象,spring 提供了 transactionTemplate 模板来实现编程式事务管理。

public class BankServiceImpl implements BankService {
    private BankDao bankDao;
    private TransactionTemplate transactionTemplate;

    public boolean transfer(final Long fromId, final Long toId, final double amount) {
        return (Boolean) transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {
                Object result;
                try {
                    result = bankDao.transfer(fromId, toId, amount);
                } catch (Exception e) {
                    status.setRollbackOnly();
                    result = false;
                    System.out.println("Transfer Error!");
                }
                return result;
            }
        });
    }
}

编程式事务与声明式事务的区别:

编程式事务是自己写事务处理的类,然后调用。

声明式事务是在配置文件中配置,一般搭配在框架里面使用。