Java面试题-day20 Spring

Spring

1. Spring特点

1) 为何使用Spring

Spring是一个轻量级J2EE框架。它的主要功能有控制反转(IoC)、面向切面编程 AOP)、面向接口开发、事务管理、还可以包容其它框架,使系统中用到的其它框架耦合程度大大降低,拓展性强、简单易用好管理。

2. IOC

1) Spring中,如何给对象的属性赋值?

  1. 通过构造函数
  2. 通过set方法给属性注入值
  3. 自动装配(了解)
    byName通过参数名自动装配,如果一个bean的name 和另外一个bean的 property 相同就自动装配。
    byType通过参数的数据类型自动自动装配,如果一个bean的数据类型和另 外一个bean的property属性的数据类型兼容,就自动装配必须确保 该类型在IOC容器中只有一个对象;否则报错。

4.注解
使用注解步骤:
1)先引入context名称空间
xmlns:context=“http://www.springframework.org/schema/context”

2)开启注解扫描
< context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>

3)使用注解

通过注解的方式,把对象加入ioc容器。
创建对象以及处理对象依赖关系,相关的注解:
@Component指定把一个对象加入IOC容器
@Repository作用同@Component;在持久层使用
@Service作用同@Component;在业务逻辑层使用
@Controller作用同@Component;在控制层使用
@Resource属性注入
总结:
1)使用注解,可以简化配置,且可以把对象加入IOC容器,及处理依赖关系(DI)
2)注解可以和XML配置一起使用。
3)@Resource的作用相当于@Autowired,只不过@Autowired按byType自动 注入,而@Resource默认按 byName自动注入罢了

2) bean对象创建的细节

1) 对象创建:单例/多例
scope=“singleton”, 默认值,即默认是单例 【service/dao/工具类】
scope=“prototype”, 多例; 【Action对象】
Spring的单例bean是线程安全的
2) 什么时候创建?
scope=“prototype” 在用到对象的时候,才创建对象。
scope=“singleton” 在启动(容器初始化之前),就已经创建了bean,且整个应用只有一个。
3)是否延迟创建
lazy-init=“false” 默认为false, 不延迟创建,即在启动时候就创建对象
lazy-init=“true” 延迟初始化,在用到对象的时候才创建对象(只对单例有效)
4) 创建对象之后,初始化/销毁
init-method=“init_user” 【对应对象的init_user方法,在对象创建爱之后执行】
destroy-method=“destroy_user” 【在调用容器对象的destriy方法时候执行,(容器用实现类)】

3) Bean的作用域?

1.singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
2. prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
3.request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
4.Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

4) IOC 容器对 Bean 的生命周期

  1. 通过构造器或工厂方法创建 Bean 实例
  2. 为 Bean 的属性设置值和对其他 Bean 的引用
  3. 将 Bean实例传递给 Bean 后置处理器的
    postProcessBeforeInitialization 方法
  4. 调用 Bean 的初始化方法(init-method)将 Bean 实例传递给 Bean 后置处理器的postProcessAfterInitialization 方法,Bean 可以使用了
  5. 当容器关闭时, 调用 Bean 的销毁方法(destroy-method)

5) 讲下BeanFactory和ApplicationContext的区别?

BeanFactory是Spring容器顶级核心接口,比较早,但功能比较少,getBean就是BeanFactory定义的。
ApplicationContext是Spring里面的另外一个容器顶级接口,它继承于BeanFactory,但是提供的功能譬如校验,国际化,监听,对Bean的管理功能比较多,一般使用ApplicationContext。

3. AOP

1) 代理模式

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过 代理访问目标对象。这样好处:可以在目标对象实现的基础上,增强额外的 功能操作。(扩展目标对象的功能)。
静态代理:要实现与目标对象一样的接口
总结静态代理:
1)可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
2)缺点:
–》因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类 太多。
–》一旦接口增加方法,目标对象与代理对象都要维护。
解决:可以使用动态代理。

动态代理
1)代理对象,不需要实现接口;
2)代理对象的生成,是利用JDKAPI,动态的在内存中构建代理对象
动态代理总结:代理对象不需要实现接口,但是目标对象一定要实现接口;否则不 能用动态代理!

Cglib代理
也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。
JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。 如果想代理没有实现接口的类,就可以使用CGLIB实现。
CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java 接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供 方法的interception(拦截)。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生 成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文 件的格式和指令集都很熟悉。

扫描二维码关注公众号,回复: 13170997 查看本文章

2) AOP

Aop, aspect object programming 面向切面编程

功能:让关注点代码与业务代码分离!关注点,重复代码就叫做关注点;
切面,关注点形成的类,就叫切面(类)!
面向切面编程,就是指对很多功能都有的重复的代码抽取,再在运行的时候往 网业务方法上动态植入“切面类代码”。
切入点,执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法;给指定的类在运行的 时候植入切面类代码。
分析总结:
关注点代码,就是指重复执行的代码。
业务代码与关注点代码分离,好处?
–关注点代码写一次即可;
-开发者只需要关注核心业务;
-运行时期,执行核心业务代码时候动态植入关注点代码;【代理】
AOP一般的使用场景?
缓存、权限、错误处理、持久化、资源池、同步、事物、日志跟踪等

4. 事务

1) 描述在系统中如何使用了Spring的事务控制

Spring事务包括编程式事务和声明式事务。在系统中使用了声明式的事务管理是用Spring的AOP来实现的;配置了只读事务和回滚事务(传播行为为REQUIRED)当出现错误后进行回滚操作。在项目中通过aop切入事务到serivce层,这样做能使一次业务逻辑操作如果包括几个数据库操作都控制在一个事务中。

2) 如何管理事务,事务是只读的还是读写的,对于查询的find()是只读,对于保存的save()是读写?

如果一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL 执行期间的读一致性;
如果一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条 查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL 查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一 致的状态,此时,应该启用事务支持
read-only="true"表示该事务为只读事务,比如上面说的多条查询的这种情况可 以使用只读事务,由于只读事务不存在数据的修改,因此数据库将会为只读事 务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回 滚log。
指定只读事务的办法为:
bean配置文件中,prop属性增加“read-Only”
或者用注解方式@Transactional(readOnly=true)
Spring中设置只读事务是利用上面两种方式(根据实际情况)
在将事务设置成只读后,相当于将数据库设置成只读数据库,此时若要进行写 的操作,会出现错误。

3) Spring的事务是如何配置的?

先配置事务管理器TransactionManager,不同的框架有不同属性。
再配置事务通知和属性,通过tx:advice。
配置<aop:config>,设置那些方法或者类需要加入事务。

4) 事务传播行为

Propagation.REQUIRED(spring默认的事务)
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务,就会加入当前的事务;
Propagation.SUPPORTS 如果有事务则加入事务,没有则无事务运行。
Propagation.REQUIRED_NEW
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务:事务会挂起;会始终开启一个新的 事务,执行完后;刚才挂起的事务才继续运行。

5) 事务并发会引起什么问题,怎么解决?

		事务并发会引起脏读,幻读,不可重复读等问题,设定事务的隔离级别可以解决。

猜你喜欢

转载自blog.csdn.net/m0_56368068/article/details/121070675