Java 面试题 (六) --------- 框架相关

news2025/1/14 1:01:12

1、什么是 Spring 框架?Spring 框架有哪些主要模块?

Spring是一个控制反转和面向切面的容器框架。

Spring有七大功能模块:

1、Core

Core模块是Spring的核心类库,Core实现了IOC功能。

2、AOP

Apring AOP模块是Spring的AOP库,提供了AOP(拦截器)机制,并提供常见的拦截器,供用户自定义和配置。

3、orm

提供对常用ORM框架的管理和支持,hibernate、mybatis等。

4、Dao

Spring提供对JDBC的支持,对JDBC进行封装。

5、Web

对Struts2的支持。

6、Context

Context模块提供框架式的Bean的访问方式,其它程序可以通过Context访问Spring的Bean资源,相当于资源注入。

7、MVC

MVC模块为spring提供了一套轻量级的MVC实现,即Spring MVC。

2、使用 Spring 框架能带来哪些好处?

1、轻量级框架、容器

Spring是一个容器,管理对象的生命周期和配置。基于一个可配置原型prototype,你的bean可以使单利的,也可以每次需要时都生成一个新的实例。

2、控制反转IOC

Spring通过控制反转实现松耦合。

3、支持AOP

Spring提供对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。

4、轻量级框架

5、方便测试

Spring提供Junit4的支持,可以通过注解方便测试spring程序。

6、对Java中很多API进行了封装

7、方便集成各种优秀框架

如Struts、hibernate、mybstis。

8、支持声明式事务处理

只需通过配置就可以完成对事务的管理,而无须手动编程。

3、Spring IOC、AOP举例说明

1、IOC理论的背景

我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑。

如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针、分针和秒针顺时针旋转,从而在表盘上产生正确的时间。图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。
齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间的耦合关系是无法避免的,也是必要的,这是协同工作的基础。现在,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

耦合关系不仅会出现在对象与对象之间,也会出现在软件系统的各模块之间,以及软件系统和硬件系统之间。如何降低系统之间、模块之间和对象之间的耦合度,是软件工程永远追求的目标之一。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson提出了IOC理论,用来实现对象之间的“解耦”,目前这个理论已经被成功地应用到实践当中,很多的J2EE项目均采用了IOC框架产品Spring。

2、什么是控制反转

IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为“控制反向”或者“控制倒置”。
1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的基本思想,前面我们已经讲了很多了,不再赘述,简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦,如下图:

在这里插入图片描述

大家看到了吧,由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。
我们再来做个试验:把上图中间的IOC容器拿掉,然后再来看看这套系统(拿掉IoC容器后的系统)
在这里插入图片描述
我们现在看到的画面,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样的话,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,如果真能实现IOC容器,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟别人没有任何关系!
我们再来看看,控制反转(IOC)到底为什么要起这么个名字?我们来对比一下:
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。
软件系统在引入IOC容器之后,这种情形就完全改变了,如图3所示,由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。
通过前后的对比,我们不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

3、IOC的别名:依赖注入(DI)

2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

我们举一个生活中的例子,来帮助理解依赖注入的过程。大家对USB接口和USB设备应该都很熟悉吧,USB为我们使用电脑提供了很大的方便,现在有很多的外部设备都支持USB接口。

现在,我们利用电脑主机和USB接口来实现一个任务:从外部USB设备读取一个文件。
电脑主机读取文件的时候,它一点也不会关心USB接口上连接的是什么外部设备,而且它确实也无须知道。它的任务就是读取USB接口,挂接的外部设备只要符合USB接口标准即可。所以,如果我给电脑主机连接上一个U盘,那么主机就从U盘上读取文件;如果我给电脑主机连接上一个外置硬盘,那么电脑主机就从外置硬盘上读取文件。挂接外部设备的权力由我作主,即控制权归我,至于USB接口挂接的是什么设备,电脑主机是决定不了,它只能被动的接受。电脑主机需要外部设备的时候,根本不用它告诉我,我就会主动帮它挂上它想要的外部设备,你看我的服务是多么的到位。这就是我们生活中常见的一个依赖注入的例子。在这个过程中,我就起到了IOC容器的作用。
通过这个例子,依赖注入的思路已经非常清楚:当电脑主机读取文件的时候,我就把它所要依赖的外部设备,帮他挂接上。整个外部设备注入的过程和一个被依赖的对象在系统运行时被注入另外一个对象内部的过程完全一样。
我们把依赖注入应用到软件系统中,再来描述一下这个过程:
对象A依赖于对象B,当对象 A需要用到对象B的时候,IOC容器就会立即创建一个对象B送给对象A。IOC容器就是一个对象制造工厂,你需要什么,它会给你送去,你直接使用就行了,而再也不用去关心你所用的东西是如何制成的,也不用关心最后是怎么被销毁的,这一切全部由IOC容器包办。
在传统的实现中,由程序内部代码来控制组件之间的关系。我们经常使用new关键字来实现两个组件之间关系的组合,这种实现方式会造成组件之间耦合。IOC很好地解决了该问题,它将实现组件间关系从程序内部提到外部容器,也就是说由容器在运行期将组件间的某种依赖关系动态注入组件中。

4、IOC为我们带来了什么好处

我们还是从USB的例子说起,使用USB外部设备比使用内置硬盘,到底带来什么好处?
第一、USB设备作为电脑主机的外部设备,在插入主机之前,与电脑主机没有任何的关系,只有被我们连接在一起之后,两者才发生联系,具有相关性。所以,无论两者中的任何一方出现什么的问题,都不会影响另一方的运行。这种特性体现在软件工程中,就是可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障。代码中的每一个Class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。
第二、USB设备和电脑主机的之间无关性,还带来了另外一个好处,生产USB设备的厂商和生产电脑主机的厂商完全可以是互不相干的人,各干各事,他们之间唯一需要遵守的就是USB接口标准。这种特性体现在软件开发过程中,好处可是太大了。每个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用去关心其它的人工作进展,因为你的任务跟别人没有任何关系,你的任务可以单独测试,你的任务也不用依赖于别人的组件,再也不用扯不清责任了。所以,在一个大中型项目中,团队成员分工明确、责任明晰,很容易将一个大的任务划分为细小的任务,开发效率和产品质量必将得到大幅度的提高。
第三、同一个USB外部设备可以插接到任何支持USB的设备,可以插接到电脑主机,也可以插接到DV机,USB外部设备可以被反复利用。在软件工程中,这种特性就是可复用性好,我们可以把具有普遍性的常用组件独立出来,反复利用到项目中的其它部分,或者是其它项目,当然这也是面向对象的基本特征。显然,IOC不仅更好地贯彻了这个原则,提高了模块的可复用性。符合接口标准的实现,都可以插接到支持此标准的模块中。
第四、同USB外部设备一样,模块具有热插拔特性。IOC生成对象的方式转为外置方式,也就是把对象生成放在配置文件里进行定义,这样,当我们更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拨的特性。
以上几点好处,难道还不足以打动我们,让我们在项目开发过程中使用IOC框架吗?

5、IOC容器的技术剖析

IOC中最基本的技术就是“反射(Reflection)”编程,目前.Net C#、Java和PHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。这种编程方式可以让对象在生成时才决定到底是哪一种对象。反射的应用是很广泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把“反射”做为最基本的技术手段。
反射技术其实很早就出现了,但一直被忽略,没有被进一步的利用。当时的反射编程方式相对于正常的对象生成方式要慢至少得10倍。现在的反射技术经过改良优化,已经非常成熟,反射方式生成对象和通常对象生成方式,速度已经相差不大了,大约为1-2倍的差距。
我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

6、IOC容器的一些产品

Sun ONE技术体系下的IOC容器有:轻量级的有Spring、Guice、Pico Container、Avalon、HiveMind;重量级的有EJB;不轻不重的有JBoss,Jdon等等。Spring框架作为Java开发中SSH(Struts、Spring、Hibernate)三剑客之一,大中小项目中都有使用,非常成熟,应用广泛,EJB在关键性的工业级项目中也被使用,比如某些电信业务。
.Net技术体系下的IOC容器有:Spring.Net、Castle等等。Spring.Net是从Java的Spring移植过来的IOC容器,Castle的IOC容器就是Windsor部分。它们均是轻量级的框架,比较成熟,其中Spring.Net已经被逐渐应用于各种项目中。

7、使用IOC框架应该注意什么

使用IOC框架产品能够给我们的开发过程带来很大的好处,但是也要充分认识引入IOC框架的缺点,做到心中有数,杜绝滥用框架。

(1)软件系统中由于引入了第三方IOC容器,生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。

(2)由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗。如果你要追求运行效率的话,就必须对此进行权衡。

(3)、具体到IOC框架产品(比如:Spring)来讲,需要进行大量的配制工作,比较繁琐,对于一些小的项目而言,客观上也可能加大一些工作成本。

(4)IOC框架产品本身的成熟度需要进行评估,如果引入一个不成熟的IOC框架产品,那么会影响到整个项目,所以这也是一个隐性的风险。
我们大体可以得出这样的结论:一些工作量不大的项目或者产品,不太适合使用IOC框架产品。另外,如果团队成员的知识能力欠缺,对于IOC框架产品缺乏深入的理解,也不要贸然引入。最后,特别强调运行效率的项目或者产品,也不太适合引入IOC框架产品,象WEB2.0网站就是这种情况。

4、什么是控制反转(IOC)?什么是依赖注入?

借助Spring实现具有依赖关系的对象之间的解耦。

对象A运行需要对象B,由主动创建变为IOC容器注入,这便是控制反转。

获得依赖对象的过程被反转了,获取依赖对象的过程由自身创建变为由IOC容器注入,这便是依赖注入。

5、BeanFactory 和 ApplicationContext 有什么区别?

1、BeanFactory是Spring的最底层接口,包含bean的定义,管理bean的加载,实例化,控制bean的生命周期,特点是每次获取对象时才会创建对象。

ApplicationContext是BeanFactory的子接口,拥有BeanFactory的全部功能,并且扩展了很多高级特性,每次容器启动时就会创建所有的对象。

ApplicationContext的额外功能:

  • 继承MessageSource,支持国际化;
  • 统一的资源文件访问方式;
  • 提供在监听器中注册bean;
  • 同时加载过个配置文件;
  • 载入多个(有继承关系)上下文,使得每个上下文都专注于一个特定的层次,比如应用的web层;

2、BeanFactory通常以编程的方式被创建,ApplicationContext可以以声明的方式创建,如使用ContextLoader。

3、BeanFactory 和 ApplicationContext都支持BeanPostProcessor,BeanFactoryPostProcessor,但BeanFactory需要手动注册,ApplicationContext则是自动注册。

6、什么是 JavaConfig?

JavaConfig是Spring3.0新增的概念,就是以注解的形式取代Spring中繁琐的xml文件。

JavaConfig结合了xml的解耦和java编译时检查的优点。

  • @Configuration,表示这个类是配置类;

  • @ComponentScan,相当于xml的<context:componentScan basepackage=>

  • @Bean,相当于xml的<bean id="student" class="com.fancy.entity">

  • @EnableWebMvc,相当于xml的 <mvc:annotation-driven>

  • @ImportResource,相当于xml的<import resource="application-context-cache.xml">

  • @PropertySource,用于读取 properties 配置文件;

  • @Profile,一般用于多环境配置,激活时可用@ActiveProfile("dev")注解;

7、什么是 ORM 框架?

ORM(Object-relational mapping),对象关系映射。

是为了解决面向对象与关系型数据库存在的不匹配问题。

ORM框架的优点:

  • 开发效率更高
  • 数据访问更抽象、轻便
  • 支持面向对象封装

8、Spring 有几种配置方式?

1、xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <bean id="jackma" class="com.fancy.dto.User">
        <property name="name" value="jackma" />
        <property name="age" value="55" />
        <property name="dog" ref="jm" />
     </bean>
 
    <bean id="jm" class="com.fancy.dto.Dog">
        <property name="name" value="jack" />
        <property name="breed" value="金毛" />
        <property name="age" value="2" />
    </bean>
</beans>

2、基于注解的方式

项目越来越大,基于xml配置太麻烦,Spring 2.x时代提供了声明bean的注解。

(1)Bean的定义

@Component、@Controller、@Service、@Repository。

(2)Bean的注入

@Autowire

3、基于Java的方式

Spring 3.x以后,可以通过Java代码装配Bean。

@Configuration
public class DemoConfig {
    @Bean
    public User zs(){
        return new User();
    }
    @Bean
    public Dog dog(){
        return  new Dog();
    }
    @Bean  //两个狗
    public Dog haqi(){
        return new Dog();
    }
}
@Component("zs")
public class User {
    private String name;
    private int age;
    private Dog dog;
 
  //get,set方法略
}

原来就是配置类啊,通过@Bean、@Component、getBean方式进行Bean的注册和发现。

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

  • 通过构造器或工厂方法创建bean实例;
  • 为bean的属性赋值;
  • 调用bean的初始化方法;
  • 使用bean;
  • 当容器关闭时,调用bean的销毁方法;

10、Spring Bean 的作用域之间有什么区别?

Spring容器中的bean可以分为5个范围:

  • singleton:这种bean范围是默认的,这种范围确保不管接受多少请求,每个容器中只有一个bean的实例,单例模式;
  • prototype:为每一个bean提供一个实例;
  • request:在请求bean范围内为每一个来自客户端的网络请求创建一个实例,在请求完毕后,bean会失效并被垃圾回收器回收;
  • session:为每个session创建一个实例,session过期后,bean会随之消失;
  • global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet公用全局的存储变量的话,那么全局变量需要存储在global-session中。

11、如何在 Spring Boot 中禁用 Actuator 端点安全性?

默认情况下,所有敏感的 HTTP 端点都是安全的,只有具有 Actuator 角色的用户才能访问它们。安全性是使用标准的HTTPServletRequest.isUserInRole方法实施的。我们可以使用management.security.enable = false来禁用安全性。只有在执行机构端点在防火墙后访问时,才建议禁用安全性。

12、什么是 Spring inner beans?

在Spring框架中,无论何时bean被使用时,当仅被调用一个属性。可以将这个bean声明为内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现。比如,在我们的应用程序中,一个Customer类引用了一个Person类,我们要做的是创建一个Person实例,然后再Customer内部使用。


package com;
 
public class Customer {
    private Person person;
}
 
class Person {
    private int id;
    private String name;
    private int age;
}
<bean id="CustomerBean" class="com.Customer">
	<property name="person">
		<bean class="com.person">
			<property name="id" value=1 />
			<property name="name" value="fancy" />
			<property name="age" value=18 />
		</bean>
	</property>
</bean>

13、Spring 框架中的单例 Beans 是线程安全的么?

Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态,所以在某种程度上说Spring的单例bean时线程安全的。如果你的bean有多种状态的话,比如view model,就需要自行保证线程安全啦。

最浅显的解决办法就是将多态bean的作用域由singleton变更为prototype。

14、请解释 Spring Bean 的自动装配?

Spring 支持 IOC,自动装配不用类实例化,直接从bean 容器中取。

1、配置在xml中

<bean id="employeeDAO" class="com.guor.EmployeeDAOImpl" autowire="byName" />

2、@Autowired自动装配

15、如何开启基于注解的自动装配?

要使用 @Autowired,需要注册 AutowiredAnnotationBeanPostProcessor,可以有以下两种方式来实现:

引入配置文件中的 <bean>下引入 <context:annotation-config>

<beans>
    <context:annotation-config />
</beans>

在 bean 配置文件中直接引入AutowiredAnnotationBeanPostProcessor

<beans>
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>

16、spring mvc 和 struts 的区别是什么?

1、拦截机制的不同

Struts2是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype,然后通过setter,getter吧request数据注入到属性。Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了,只能设计为多例。

SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。

Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。

2、底层框架的不同

Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

3、性能方面

Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。所以,SpringMVC开发效率和性能高于Struts2。

4、配置方面

Spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高。

17、请举例解释 @Required 注解?

@Required注解应用于bean属性的setter方法,它表明影响的bean属性在配置时必须放在XML配置文件中。

18、请举例说明 @Qualifier 注解?

如果在xml中定义了一种类型的多个bean,同时在java注解中又想把其中一个bean对象作为属性,那么此时可以使用@Qualifier加@Autowired来达到这一目的,若不加@Qualifier这个注解,在运行时会出现“ No qualifying bean of type [com.tutorialspoint.Student] is defined: expected single matching bean but found 2: student1,student2”这个异常。

19、如何防止表单重复提交

  • 通过JavaScript屏蔽提交按钮(不推荐)

  • 给数据库增加唯一键约束(简单粗暴)

  • 利用Session防止表单重复提交(推荐)

  • 使用AOP自定义切入实现

20、Spring中都应用了哪些设计模式?

1、简单工厂模式

简单工厂模式的本质就是一个工厂类根据传入的参数,动态的决定实例化哪个类。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象。

2、工厂方法模式

应用程序将对象的创建及初始化职责交给工厂对象,工厂Bean。

定义工厂方法,然后通过config.xml配置文件,将其纳入Spring容器来管理,需要通过factory-method指定静态方法名称。

3、单例模式

Spring用的是双重判断加锁的单例模式,通过getSingleton方法从singletonObjects中获取bean。

 /**
 * Return the (raw) singleton object registered under the given name.
 * <p>Checks already instantiated singletons and also allows for an early
 * reference to a currently created singleton (resolving a circular reference).
 * @param beanName the name of the bean to look for
 * @param allowEarlyReference whether early references should be created or not
 * @return the registered singleton object, or {@code null} if none found
 */
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

4、代理模式

Spring的AOP中,使用的 Advice(通知)来增强被代理类的功能。Spring实现AOP功能的原理就是代理模式(① JDK动态代理,② CGLIB字节码生成技术代理。)对类进行方法级别的切面增强。

5、装饰器模式

装饰器模式:动态的给一个对象添加一些额外的功能。

Spring的ApplicationContext中配置所有的DataSource。这些DataSource可能是不同的数据库,然后SessionFactory根据用户的每次请求,将DataSource设置成不同的数据源,以达到切换数据源的目的。

在Spring中有两种表现:

一种是类名中含有Wrapper,另一种是类名中含有Decorator。

6、观察者模式

定义对象间的一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

Spring中观察者模式一般用在listener的实现。

7、策略模式

策略模式是行为性模式,调用不同的方法,适应行为的变化 ,强调父类的调用子类的特性 。

getHandler是HandlerMapping接口中的唯一方法,用于根据请求找到匹配的处理器。

8、模板方法模式

Spring JdbcTemplate的query方法总体结构是一个模板方法+回调函数,query方法中调用的execute()是一个模板方法,而预期的回调doInStatement(Statement state)方法也是一个模板方法。

21、请举例说明如何在 Spring 中注入一个 Java Collection?

Spring注入有四种方式,

  • set注入;
  • 构造器注入;
  • 基于注解的注入;
  • xml配置文件注入;

想要注入java collection,就是注入集合类:

  • list
  • set
  • map
  • props:该标签支持注入键和值都是字符串类型的键值对。

list和set都使用value标签;map使用entry标签;props使用prop标签

22、mybatis 中 #{}${} 的区别是什么?

#{}带引号,${}不带引号;
#{}可以防止SQL注入;
${}常用于数据库表名、order by子句;
一般能用#{}就不要使用${};

23、mybatis 是否支持延迟加载?延迟加载的原理是什么?

1、mybatis 是否支持延迟加载?

延迟加载其实就是讲数据加载时机推迟,比如推迟嵌套查询的时机。

延迟加载可以实现先查询主表,按需实时做关联查询,返回关联表结果集,一定程度上提高了效率。

mybatis仅支持关联对象association和关联集合对象collection的延迟加载,association是一对一,collection是一对多查询,在mybatis配置文件中可以配置lazyloadingEnable=true/false。

2、延迟加载的原理是什么?

使用CGLIB为目标对象建立代理对象,当调用目标对象的方法时进入拦截器方法。

比如调用a.getB().getName(),拦截器方法invoke()发现a.getB()为null,会单独发送事先准备好的查询关联B对象的sql语句,把B查询出来然后调用a.setB(b),也是a的对象的属性b就有值了,然后调用getName(),这就是延迟加载的原理。

24、说一下 mybatis 的一级缓存和二级缓存?

一级缓存是session级别的缓存,默认开启,当查询一次数据库时,对查询结果进行缓存,如果之后的查询在一级缓存中存在,则无需再访问数据库;

二级缓存是sessionFactory级别的缓存,需要配置才会开启。当进行sql语句查询时,先查看一级缓存,如果不存在,访问二级缓存,降低数据库访问压力。

25、mybatis 有哪些执行器(Executor)?

1、mybatis 有三种基本的 Executor 执行器:

(1)、SimpleExecutor

每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

(2)、PauseExecutor

执行update或select,以sql做为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而且放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。

(3)、BatchExecutor

执行update,将所有sql通过addBatch()都添加到批处理中,等待统一执行executeBatch(),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

2、作用范围:

Executor的这些特点,都严格限制在SqlSession生命周期范围内。

3、Mybatis中如何指定使用哪一种Executor执行器?

在mybatis的配置文件中,可以指定默认的ExecutorType执行器类型,也可以手动给DefaultSqlSessionFactory的创建SqlSession的方法传递ExecutorType类型参数。

26、mybatis 和 hibernate 的区别有哪些?

1、两者最大的区别

针对简单逻辑,都有对应的代码生成工具,可以生成简单基本的dao层方法;

针对高级查询,mybatis要手动编写sql语句和resultMap,而hibernate有良好的映射机制;

2、开发难度对比

hibernate > mybatis

3、日志统计

hibernate有自己的日志统计功能,而mybatis需要借助log4j来记录日志。

4、数据库扩展比较

hibernate > mybatis

5、缓存机制比较

因为hibernate对查询对象有良好的管理机制,用户无需关心sql,所以使用二级缓存如果出现脏数据,系统会报错。

而mybatis,如果不能获取最新数据,应该避免缓存的使用,脏数据的出现会给系统的正常运行带来很大的隐患。

6、如何选择

mybatis需要编写sql和映射规则,工作量大于hibernate;
mybatis支持的工具也有限,不能像hibernate那样有许多插件可以帮助生成映射代码和关联关系;
对于性能要求不太苛刻的系统,比如管理系统、ERP等推荐hibernate;
对于性能要求高、响应快、灵活的系统,比如电商系统,推荐使用mybatis;

27、mybatis一级缓存、二级缓存

1、一级缓存:指的是mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入sqlSession中,再次查询的时候,先去sqlSession中查询,有的话直接拿出,当sqlSession消失时,mybatis的一级缓存也就消失了,当调用sqlSession的修改、添加、删除、commit()、close()等方法时,会清空一级缓存。

2、二级缓存:指的是mybatis中的sqlSessionFactory对象的缓存,由同一个sqlSessionFactory对象创建的sqlSession共享其缓存,但是其中缓存的是数据而不是对象。当命中二级缓存时,通过存储的数据构造成对象返回。查询数据的时候,查询的流程是二级缓存 > 一级缓存 > 数据库。

3、如果开启了二级缓存,sqlSession进行close()后,才会把sqlSession一级缓存中的数据添加到二级缓存中,为了将缓存数据取出执行反序列化,还需要将要缓存的pojo实现Serializable接口,因为二级缓存数据存储介质多种多样,不一定只存在内存中,也可能存在硬盘中。

4、mybatis框架主要是围绕sqlSessionFactory进行的,具体的步骤:

定义一个configuration对象,其中包含数据源、事务、mapper文件资源以及影响数据库行为属性设置settings。
通过配置对象,则可以创建一个sqlSessionFactoryBuilder对象。
通过sqlSessionFactoryBuilder获得sqlSessionFactory实例。
通过sqlSessionFactory实例创建qlSession实例,通过sqlSession对数据库进行操作。

28、mybatis如何防止sql注入

注意:但凡是sql注入漏洞的程序,都是因为程序要接受来自客户端用户输入的变量或URL传递的参数,并且这个变量或参数是组成sql语句的一部分,对于用户输入的内容或传递的参数,我们应该要时刻保持警惕,这是安全领域里的【外部数据不可信任】的原则,纵观web安全领域的各种攻击方式,大多数都是因为开发者违反了这个原则而导致的,所以自然能想到,就是变量的检测、过滤、验证下手,确保变量是开发者所预想的。

1、检查变量数据类型和格式

数据类型检查,sql执行前,要进行数据类型检查,如果是邮箱,参数就必须是邮箱的格式,如果是日期,就必须是日期格式;

只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击。

如果上述例子中id是int型的,效果会怎样呢?无法注入,因为输入注入参数会失败。比如上述中的name字段,我们应该在用户注册的时候,就确定一个用户名规则,比如5-20个字符,只能由大小写字母、数字以及汉字组成,不包含特殊字符。此时我们应该有一个函数来完成统一的用户名检查。不过,仍然有很多场景并不能用到这个方法,比如写博客,评论系统,弹幕系统,必须允许用户可以提交任意形式的字符才行,否则用户体验感太差了。

2、过滤特殊符号

3、绑定变量,使用预编译语句

29、什么是 Spring Boot?Spring Boot 有哪些优点?

1、Spring Boot简介

基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突、引用的不稳定性得到了解决。

2、Spring Boot 有哪些优点?

快速构建项目,可以选一些必要的组件;
对主流框架的无配置集成;
内嵌Tomcat容器,项目可独立运行;
删除了繁琐的xml配置文件;
极大地提高了开发和部署效率;
提供starter,简化maven配置;

3、SpringBoot有哪些缺点?

版本迭代速度快,一些模块改动很大;
由于无须配置,报错时很难定位;

151、Spring Boot 中的监视器是什么?
监听器也叫listener,是servlet的监听器,可以用于监听web应用程序中某些对象的创建、销毁、增加、修改、删除等动作的发生,然后做出相应的响应处理。当范围对象的状态发生变化时,服务器自动调用监听器对象中的方法,常用于系统加载时进行信息初始化,统计在线人数和在线用户,统计网站的访问量。

配置监听器的方法:

通过@Component把监听器加入Spring容器中管理;
在application.properties中添加context.listener.classes配置;
在方法上加@EventListener注解;

30、什么是 YAML?

YAML是JSON的一个超集,可以非常方便地将外部配置以层次结构形式存储起来。YAML可以作为properties配置文件的替代。

YAML使用的注意事项:

在properties文件中是以".“进行分割的,在yml中是用”.“进行分割的;
yml的数据格式和json的格式很像,都是K-V格式,并且通过”:"进行赋值;
每个冒号后面一定要加一个空格;

31、如何使用 Spring Boot 实现分页和排序?

使用Spring Data Jpa可以实现将可分页的传递给存储库方法。

32、如何使用 Spring Boot 实现异常处理?

1、使用 @ExceptionHandler 注解处理局部异常(只能处理当前controller中的ArithmeticException和NullPointerException异常,缺点就是只能处理单个controller的异常)

@Controller
public class ExceptionHandlerController {
	
	@RequestMapping("/excep")
	public String exceptionMethod(Model model) throws Exception {
		String a=null;
		System.out.println(a.charAt(1));
		int num = 1/0;
		model.addAttribute("message", "没有抛出异常");
		return "index";
	}
 
	@ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
	public String arithmeticExceptionHandle(Model model, Exception e) {
		model.addAttribute("message", "@ExceptionHandler" + e.getMessage());
		return "index";
	}
}

2、使用 @ControllerAdvice + @ExceptionHandler 注解处理全局异常(value后面可以填写数组)

@ControllerAdvice
public class ControllerAdviceException {
	
	@ExceptionHandler(value = {NullPointerException.class})
	public String NullPointerExceptionHandler(Model model, Exception e) {
		model.addAttribute("message", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage());
		return "index";
	}
}

3、配置 SimpleMappingExceptionResolver 类处理异常(配置类)

@Configuration
public class SimpleMappingException {
	@Bean
	public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
 
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		Properties mappings = new Properties();
		//第一个参数为异常全限定名,第二个为跳转视图名称
		mappings.put("java.lang.NullPointerException", "index");
		mappings.put("java.lang.ArithmeticException", "index");
		//设置异常与视图映射信息的
		resolver.setExceptionMappings(mappings);
		return resolver;
	}
}

4、实现 HandlerExceptionResolver 接口处理异常

@Configuration
public class HandlerException implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
 
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message", "实现HandlerExceptionResolver接口");
 
		//判断不同异常类型,做不同视图跳转
		if(ex instanceof NullPointerException){
			modelAndView.setViewName("index");
		}
		if(ex instanceof ArithmeticException){
			modelAndView.setViewName("index");
		}
		return modelAndView;
	}
}

33、打包和部署

Spring和Spring Boot都支持maven和Gradle通用打包管理技术。

Spring Boot相对Spring的一些优点:

提供嵌入式容器支持;
使用命令java -jar独立运行jar;
部署时可以灵活指定配置文件;
最近项目是分布式的项目,都是通过分项目打包部署,然后部署在docker中运行。

34、Spring Boot如何访问不同的数据库

可以使用druidDataSource创建DataSource,然后通过jdbcTemplate执行sql。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/117683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FLTK的UI设计工具FLUID使用方法总结

tags: FLTK C GUI 写在前面 终于又捡起来FLTK了, 先来看看怎么通过FLUID创建一个图形界面并完成回调函数的创建, 参考的是官方教程中关于创建一个CubeView程序的例子, 教程里面很多都与最新版本的FLTK界面不太一致, 但是通过我的摸索还是找出了方法. 下面来分享一下. 创建类…

centos7搭建mysql5.6

检查是否安装mysql rpm -qa | grep mysql 检查已安装的Mariadb rpm -qa | grep -i mariadb 卸载已安装的Mariadb数据库 rpm -qa | grep mariadb | xargs rpm -e --nodeps 下载mysql5.6安装包文件 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm安…

详解什么是Polygon跨链桥| Tokenview

Polygon是一个Layer2网络&#xff0c;用于解决以太坊的吞吐量和主权挑战。尽管以太坊是最受欢迎的区块链开发平台&#xff0c;但它的吞吐量很低&#xff0c;不适合某些应用程序。Polygon提供特定于应用程序的、与以太坊兼容的侧链&#xff0c;将独立链的可扩展性和独立性与以太…

自学开发技术,从入门到入行

今天我们不谈技术&#xff0c;也不聊业务&#xff0c;说说学习技术的心得。 说到学习这种事情&#xff0c;无论是学什么&#xff0c;都需要持之以恒&#xff0c;拥有坚持的决心才有可能会学到一些东西。如果只是三天打鱼&#xff0c;两天晒网的态度&#xff0c;不出差错的话&a…

ORB-SLAM2 --- Tracking::TrackLocalMap函数

目录 1.函数作用 2.函数步骤 3.code 4.函数解释 ORB-SLAM2 --- Tracking::UpdateLocalKeyFrames函数https://blog.csdn.net/qq_41694024/article/details/128307627 1.函数作用 在跟踪得到当前帧初始姿态后&#xff0c;现在对local map进行跟踪得到更多的匹配&#xff0…

《迷你世界》亿级玩家都在用的游戏场景推荐系统长啥样?

导读&#xff1a;中国TOP1沙盒游戏&#xff0c;如何解决数据存储难题&#xff1f; 提到推荐系统&#xff0c;很多人都在电商购物、资讯或娱乐平台中体验过。比如&#xff0c;你刚在某电商APP买了一部手机&#xff0c;过两天再登录时&#xff0c;首页推荐中必定有耳机、手机壳等…

【信息安全】seed-labs实验-Secret-Key Encryption Lab

目录Task 1: Frequency AnalysisTask 2: Encryption using Different Ciphers and ModesTask 4: PaddingTask 5: Error Propagation – Corrupted Cipher TextTask 6: Initial Vector (IV) and Common MistakesTask 6.1. IV ExperimentTask 6.2. Common Mistake: Use the Same …

python源代码打包成为exe文件

目录标题前言下载安装模块&#xff08;pyinstaller&#xff09;执行打包命令1、在cmd中进入项目文件2、执行pyinstaller命令成exe文件3、找到exe文件报错以及解决报错X1解决方法&#xff1a;报错X2解决方法&#xff1a;写在最后前言 大家都知道我们在pycharm中编写的源代码&am…

如何在 15 分钟内度量 DORA 指标?

在这篇文章中&#xff0c;我们将介绍 DevOps 四个关键指标——DORA 指标是什么&#xff0c;其度量难点&#xff0c;以及如何基于开源工具快速实现 DORA 指标的持续追踪。如果你熟悉 DORA 指标&#xff0c;可以直接跳到本文第二部分。 什么是 DORA 指标&#xff1f; DORA 的全…

设备树的使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、设备树的概念&#xff1f;二、设备树的作用三、如何使用设备树1.设备树的位置2.设备树的语法认识DTC、DTS、DTSI、DTB设备节点信息3.添加自己的设备树节点4.…

STM32MP157驱动开发——SPI驱动

STM32MP157驱动开发——SPI驱动一、简介1.SPI介绍2.STM32MP1 SPI介绍3. ICM-20608 简介4.Linux下的SPI框架二、驱动开发1&#xff09;IO 的 pinctrl 子节点创建与修改2&#xff09;SPI 设备节点的创建与修改3&#xff09;ICM20608驱动4&#xff09;测试App5&#xff09;运行测试…

【分享】订阅用友U8集简云连接器同步费用审批数据至用友U8系统

方案简介 集简云通过与钉钉连接平台深度融合&#xff0c;实现OA审批通过后&#xff0c;将采购、报销、收款、售后等费用审批单数据自动同步至用友U8系统&#xff0c;大大提高了企业日常采购、报销、付款等的工作效率&#xff0c;实现企业业务流程的自动化&#xff0c;为企业降…

Docker的数据管理

目录 一、数据卷 二、数据卷容器 三、容器互联 容器中管理数据主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09;数据卷容器&#xff08;Data Volume Dontainers&#xff09; 一、数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可…

5点电容式触摸屏控制芯片GT811介绍

5点电容式触摸屏控制芯片GT811简介 5点电容式触摸屏控制芯片GT811&#xff0c;采用投射式电容检测原理&#xff0c;由16个驱动通道与10个感应通道组成触摸检测网络&#xff0c;通过内置模拟放大电路、数字运算模块&#xff0c;及高性能MPU得到实时准确的触摸信息&#xff0c;并…

rocketmq安装

链接&#xff1a;https://pan.baidu.com/s/14ziQH62MeYmM8N6JsH5RcA 提取码&#xff1a;yyds 下载rocketmq-all-4.9.3-bin-release.zip 下载、修改配置 mkdir -p /app/rocketmq cd /app/rocketmqunzip rocketmq-all-4.9.3-bin-release.zip cd rocketmq-4.9.3/修改 配置文件&…

F28335第十六篇——Flash操作

文章目录前言配置方法擦除函数编写和校验函数前言 本文主要介绍如何对DSP28335进行Flash操作。 本文主要参考资料&#xff1a; TI.Flash2833x_API_Readme DSP的Flash操作需要借助官方提供API。官方提供的API主要完成Flash的擦除&#xff0c;编写&#xff0c;校验三种功能。…

八、Java 15 新特性

八、Java 15 新特性 JDK 15 在 2020 年 9 月 15 号正式发布了&#xff01;根据发布的规划&#xff0c;这次发布的 JDK 15 将是一个短期的过度版&#xff0c;只会被 Oracle 支持&#xff08;维护&#xff09;6 个月&#xff0c;直到明年 3 月的 JDK 16 发布此版本将停止维护。而…

VUE3-生命周期钩子《六》

目录 1.onMounted() 2.onUpdated() 生命周期的作用&#xff0c;页面加载的时候&#xff0c;主动执行某些程序。生命周期钩子有很多种&#xff0c;每一种都是有顺序的&#xff0c;如果不按照顺序执行的话&#xff0c;那么就不会触发某种效果&#xff0c;所以先要了解生命周期钩…

Java Web高级面试题(一)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java面试题…

常用的工具网站(网址 + 效果图)

一&#xff0c;阿里图标库 https://www.iconfont.cn/?spma313x.7781069.1998910419.d4d0a486a 二&#xff0c;AI人工智能图片放大 https://bigjpg.com/zh 三&#xff0c;一个有情怀的免费PPT模板下载网站&#xff01; https://www.ypppt.com/ 四&#xff0c;照片抠图…