高级程序员知识学习(Spring高级框架相关知识)

Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。 

Spring 框架中的设计模式

工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

单例模式:Bean默认为单例模式。

代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

Spring context模块

这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器。

Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。

Spring框架中有哪些不同的类型的事件

1.  上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

2.  上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

3.  上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

4.  上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

5.  请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

SpringIOC(spring对Bean的管理)

个人理解:SpringIOC 是spring提供对类的全生命周期的一个管理,通过利用springIOC容器来实现bean的实例化创建和销毁。IOC容器获取对象是程序在加载xml配置文件时通过反射调用构造函数来创建对象(我们开始学就是在xml里配置的)。其中的这个SpringIOC中的最为关键的是Bean的创建一个实例化过程。这个是实例化过程大致是将首先将JVM将.java文件加载到jvm内存中。然后Spring中的Beandefintion分解得到一个map的键值表的关系在通过preinstancesingletons的方法来map中的信息放入spring单例池中得到一个类的bean对象。然后在通过getBean方法来获得对象实例化的对象。这个是spring在不在外界是可以产生bean的对象。但是spring也提供一个BeanFactorProcess函数允许程序员一起来建Bean工厂,来实现对产生Bean的是实例化。

Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。Spring 启动时读取应用程序提供的 Bean 配置信息,并在 Spring 容器中生成一份相应的 Bean 配置注册表,然后根据这张注册表实例化 Bean,装配好 Bean 之间的依赖关系,为上层应用提供准备就绪的运行环境。 其中 Bean 缓存池为 HashMap 实现

BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身; ApplicationContext 面向使用Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。

 1BeanDefinitionRegistry 注册表

Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工注册BeanDefinition 对象的方法。

BeanFactory 顶层接口

2. 位于类结构树的顶端 ,它最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean, BeanFactory 的功能通过其他的接口得到不断扩展:

3ListableBeanFactory

3. 该接口定义了访问容器中 Bean 基本信息的若干方法,如查看 Bean 的个数、获取某一类型Bean 的配置名、查看容器中是否包括某一 Bean 等方法;

4 HierarchicalBeanFactory 父子级联

4. 父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器; HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean。 Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的 Bean。

5 ConfigurableBeanFactory

5. 是一个重要的接口,增强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法

6 AutowireCapableBeanFactory 自动装配

定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;

7 SingletonBeanRegistry 运行期间注册单例 Bean

定义了允许在运行期间向容器注册单实例 Bean 的方法;对于单实例(singleton)的 Bean

来说, BeanFactory 会缓存 Bean 实例,所以第二次使用 getBean() 获取 Bean 时将直接从IoC 容器的缓存中获取 Bean 实例。 Spring 在 DefaultSingletonBeanRegistry 类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器, 单实例的 Bean 以beanName 为键保存在这个 HashMap 中。

8 依赖日志框框

在初始化 BeanFactory 时,必须为其提供一种日志框架,比如使用 Log4J, 即在类路径下提供 Log4J 配置文件,这样启动 Spring 容器才不会报错。ApplicationContext 面向开发应用ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用的能。ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能:

1. ClassPathXmlApplicationContext:默认从类路径加载配置文件

2. FileSystemXmlApplicationContext:默认从文件系统中装载配置文件

3. ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。

4. MessageSource:为应用提供 i18n 国际化消息访问的功能;

5. ResourcePatternResolver :所 有 ApplicationContext 实 现类 都实 现了 类 似于PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件。

6. LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现及具体Bean 实现, ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的。

7. ConfigurableApplicationContext 扩展于 ApplicationContext, 它新增加了两个主要的方法: refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用 close()则可关闭应用上下文。

SpringBean的创建流程

实例化

1. 实例化一个 Bean, 也就是我们常说的 new。

IOC 依赖注入

2. 按照 Spring 上下文对实例化的 Bean 进行配置, 也就是 IOC 注入。

setBeanName 实现

3. 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)

方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值BeanFactoryAware 实现

4. 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,

setBeanFactory(BeanFactory)传递的是 Spring 工厂自身(可以用这个方式来获取其它 Bean,

只需在 Spring 配置文件中配置一个普通的 Bean 就可以)。13/04/2018 Page 125 of 283

ApplicationContextAware 实现

5. 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用setApplicationContext(ApplicationContext)方法,传入 Spring 上下文(同样这个方式也

可以实现步骤 4 的内容,但比 4 更好,因为 ApplicationContext 是 BeanFactory 的子接

口,有更多的实现方法)postProcessBeforeInitialization 接口实现-初始化预处理

6. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 经常被用作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用那个的方法,也可以被应用于内存或缓存技术。init-method

7. 如果 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。postProcessAfterInitialization

8. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用postProcessAfterInitialization(Object obj, String s)方法。注: 以上工作完成以后就可以应用这个 Bean 了,那这个 Bean 是一个 Singleton 的,所以一般情况下我们调用同一个 id 的 Bean 会是在内容地址相同的实例,当然在 Spring 配置文件中也可以配置非 Singleton。Destroy 过期自动清理阶段

9. 当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用那个其实现的 destroy()方法;destroy-method 自配置清理

10. 最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。

Spring框架支持以下五种bean的作用域:

    singleton : bean在每个Spring ioc 容器中只有一个实例。

    prototype:一个bean的定义可以有多个实例。

    request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

    session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

    global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

注意: 缺省的Spring bean 的作用域是Singleton。使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。

Spring框架中的单例bean是线程安全的吗?

不是,Spring框架中的单例bean不是线程安全的。

spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。

有状态就是有数据存储功能。无状态就是不会保存数据。

Spring如何处理线程并发问题?

在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

解释Spring框架中bean的生命周期

怎样开启注解装配?

注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 <context:annotation-config/>元素。

@Required 注解有什么作用

这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException

@Component, @Controller, @Repository, @Service 有何区别?

@Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。

@Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。

@Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。

@Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

spring JDBC API 中存在哪些类?

JdbcTemplate

SimpleJdbcTemplate

NamedParameterJdbcTemplate

SimpleJdbcInsert

SimpleJdbcCall

JdbcTemplate是什么

JdbcTemplate 类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。

@Autowired 注解有什么作用

@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法

@RequestMapping 注解有什么用?

@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:

    类级别:映射请求的 URL

    方法级别:映射 URL 以及 HTTP 请求方法

Spring事务管理

Spring支持两种类型的事务管理

编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

众所周知,Spring事务采用AOP的方式实现,我们从TransactionAspectSupport这个类开始分析:

1获取事务的属性(@Transactional注解中的配置)

2加载配置中的TransactionManager.

3获取收集事务信息TransactionInfo

4执行目标方法

5出现异常,尝试处理。

6清理事务相关信息

7提交事务

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional标识。

    spring 在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

Spring的属性

常量

解释

ISOLATION_DEFAULT

这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。

ISOLATION_READ_UNCOMMITTED

这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

ISOLATION_READ_COMMITTED

保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。

ISOLATION_REPEATABLE_READ

这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

ISOLATION_SERIALIZABLE

这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

(1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。

(2)基于 TransactionProxyFactoryBean的声明式事务管理

(3)基于 @Transactional 的声明式事务管理

(4)基于Aspectj AOP配置事务

6.1AOP的解释

springAOP是一种的切向编程的思想,通过springAoP实现对软件设计的原则:开闭原则。进而实现对一个类的和一个方法的增强的一种的手段。在传统的架构中都是垂直的流程体系。但是在这个过程中经常产生一些横向问题,比如log日志记录,权限验证,事务处理,性能检查的问题,通过使用的动态代理技术来实现来实现的AOP 的编程思想。

AOP的应用是:log日志记录,权限验证,事务处理,性能检查的问题。AOP在面向过程中产生的一些横向问题,抽象出来就是AOP,主要是是关心逻辑的执行的顺序时间。

6.2Spring中的动态代理实现

具体使用哪种方式生成由AopProxyFactory 根据 AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用 JDK 动态代理技术,否则使用 Cglib 来生成代理。

1JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

2如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

如何理解 Spring 中的代理?

将 Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。

Advice + Target Object = Proxy

6.3Spring AOP名词解释

(1)切面(Aspect):切面是通知和切点的结合。通知和切点共同定义了切面的全部内容。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。

(2)连接点(Join point):指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。 应用可能有数以千计的时机应用通知。这些时机被称为连接点。连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

(3)通知(Advice):在AOP术语中,切面的工作被称为通知。

(4)切入点(Pointcut):切点的定义会匹配通知所要织入的一个或多个连接点。我们通常使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。

(5)引入(Introduction):引入允许我们向现有类添加新方法或属性。

(6)目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。它通常是一个代理对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。

(7)织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期里有多少个点可以进行织入:

    编译期:切面在目标类编译时被织入。AspectJ的织入编译器是以这种方式织入切面的。

    类加载期:切面在目标类加载到JVM时被织入。需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。

运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面。

Spring切面可以应用5种类型的通知:

    前置通知(Before):在目标方法被调用之前调用通知功能;

    后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;

    返回通知(After-returning ):在目标方法成功执行之后调用通知;

    异常通知(After-throwing):在目标方法抛出异常后调用通知;

    环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

什么是切面 Aspect?

aspect由pointcount 和 advice 组成,切面是通知和切点的结合。 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中.

AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:

    如何通过 pointcut 和 advice 定位到特定的 joinpoint 上

    如何在 advice 中编写切面代码.

可以简单地认为, 使用 @Aspect 注解的类就是切面.

Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把模型-视图-控制器分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。Spring的MVC框架是围绕DispatcherServlet来设计的,它用来处理所有的HTTP请求和响应。

SpringMVC的工作流程

1)用户发送请求至前端控制器DispatcherServlet。

2)DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3)处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4)DispatcherServlet调用HandlerAdapter处理器适配器。

5)HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

6)Controller执行完成返回ModelAndView。

7)HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

8)DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

9)ViewReslover解析后返回具体View。

10)DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

11)DispatcherServlet响应用户

7.2Spring的Controller的实现是:

1扫描整个项目(Spring在启动的时候就已经扫描好了)

2拿到所有的controller的注解类

3 遍历类里面所有的对象

4 判断方法时候为@RequestMapping的注解

5 把@ResquestMapping 注解的vale的值。作为map集合的key给put进去。把menthod的方法对象作为一个value的值

6根据用户的发送请求 拿到请求中的额URL:uri

7 通过uri作为map中的key 去查看的手有返回值

8通过反射来调用这个的方法对象。

spring mvc 和 struts 的区别是什么?

拦截级别:struts2 是类级别的拦截;spring mvc 是方法级别的拦截。

数据独立性:spring mvc 的方法之间基本上独立的,独享 request 和 response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量;而 struts2 虽然方法之间也是独立的,但其所有 action 变量是共享的,这不会影响程序运行,却给我们编码和读程序时带来了一定的麻烦。

Spring MVC的控制器是不是单例模式,如果是,有什么问题,怎么解决?

答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。

Spring MVC常用的注解有哪些?

@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。

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

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

为什么tomcat回调用的Spring的中的onstartup方法?

Spring和tomcat同时遵守了Servlet的3.0的代码。通过利用的SPI  的这样的而一种机制实现的。当web容器的启动的时候在配置文件中申明那些事在web容器的启动的 需要调用的。这个时候就在META-INF配置文件中进行配置。启动项目中的springServletcontainerinitialzer的类

SpringMVC的控制器是不是单例模式?

答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。

Spring MVC怎么样设定重定向和转发的?

(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"

(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

Spring注解原理

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

Spring的注解有:基于XML的配置、基于注解的配置、基于Java的配置。和代理对象

Spring框架中的单例模式的beans的线程是否安全?

Spring框架并没有对单例bean进行任何多线程的封装处理。大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。

怎么样把ModelMap里面的数据放入Session里面?

答:可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。

如何解决POST请求中文乱码问题,GET的又如何处理呢?

解决post请求乱码问题:

在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;

get请求中文参数出现乱码解决方法有两个:

①修改tomcat配置文件添加编码与工程编码一致,如下:

②另外一种方法对参数进行重新编码:

String userName = new String(request.getParamter(“userName”).getBytes(“ISO8859-1”),“utf-8”)

有两种写法,一种是实现HandlerInterceptor接口,另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在Spring MVC的配置文件中配置拦截器即可:

<!-- 配置Spring MVC的拦截器 -->

<mvc:interceptors>

    <!-- 配置一个拦截器的Bean就可以了 默认是对所有请求都拦截 -->

    <bean id="myInterceptor" class="com.zwp.action.MyHandlerInterceptor"></bean>

    <!-- 只针对部分请求拦截 -->

    <mvc:interceptor>

       <mvc:mapping path="/modelMap.do" />

       <bean class="com.zwp.action.MyHandlerInterceptorAdapter" />

    </mvc:interceptor>

</mvc:interceptors>

介绍一下 WebApplicationContext

WebApplicationContext 继承了ApplicationContext 并增加了一些WEB应用必备的特有功能,它不同于一般的ApplicationContext ,因为它能处理主题,并找到被关联的servlet。

为什么我的事务不生效

1.如果不是Innodb存储引擎,MyISAM不支持事务。

2.没有指定rollbackFor参数。

3. 没有指定transactionManager参数,默认的transactionManager并不是我期望的,以及一个事务中涉及到了多个数据库。

4. 如果AOP使用了JDK动态代理,对象内部方法互相调用不会被Spring的AOP拦截,@Transactional注解无效。

5. 如果AOP使用了CGLIB代理,事务方法或者类不是public,无法被外部包访问到,或者是final无法继承,@transactional注解无效。

猜你喜欢

转载自blog.csdn.net/weixin_41605937/article/details/106002458