2020-12-22

2.Java 框架
2.1.Spring框架
2.1.1: 谈谈你对Spring的理解?
Spring 是一个轻量级的 IoC 和 AOP 容器框架。是为 Java 应用程序提供基础性服务的一套框架,目的是用于简化
企业应用程序的开发,它使得开发者只需要关心业务需求。
常见的配置方式有三种:基于 XML 的配置、基于注解的配置、基于 Java 的配置。
主要由以下几个模块组成:
Spring Core:核心类库,提供 IOC 服务;
Spring Context:提供框架式的 Bean 访问方式,以及企业级功能(JNDI、定时任务等);
Spring AOP:AOP 服务;
Spring DAO:对 JDBC 的抽象,简化了数据访问异常的处理;
Spring ORM:对现有的 ORM 框架的支持;
Spring Web:提供了基本的面向 Web 的综合特性,例如多方文件上传;
Spring MVC:提供面向 Web 应用的 Model-View-Controller 实现。
2.1.2:Spring中的设计模式有那些?
(1)工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例;
(2)单例模式:Bean 默认为单例模式。
(3)代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技术;
(4)模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
(5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都
会得到通知被制动更新,如 Spring 中 listener 的实现.
2.1.3:Spring中常用注解有那些?
 Spring部分:
1、声明bean的注解
@Component 组件,没有明确的角色
@Service 在业务逻辑层使用(service层)
@Repository 在数据访问层使用(dao层)
2、注入bean的注解
@Autowired:由Spring提供
@Resource:由JSR-250提供
3、@Value注解
@Value 为属性注入值
 SpringMVC部分
@Controller 声明该类为SpringMVC中的Controller
@RequestMapping 用于映射Web请求
@PathVariable 用于接收路径参数
@ResponseBody 返回json数据
@RequestBody 接收ajax请求的json数据
@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合
2.1.4:简单介绍一下Spring bean 的生命周期?
生命周期这块无非就是从创建到销毁的过程
spring容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁。
而对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。
整体来说就4个步骤:实例化bean,属性赋值,初始化bean,销毁bean
• 首先就是实例化bean,容器通过获取BeanDefinition对象中的信息进行实例化
• 然后呢就是属性赋值,利用依赖注入完成 Bean 中所有属性值的配置注入
• 接着就是初始化bean,如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
• 最后就是销毁bean,和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑
2.1.5:Spring的结构图?

2.1.6:请描述一下Spring的事务?
关于Spring事务的实现原理,这里需要抓住的就是,其是使用Aop实现的,我们知道,Aop在进行解析的时候,最终会生成一个Adivsor对象,这个Advisor对象中封装了切面织入所需要的所有信息,其中就包括最重要的两个部分就是Pointcut和Adivce属性。这里Pointcut用于判断目标bean是否需要织入当前切面逻辑;Advice则封装了需要织入的切面逻辑。如下是这三个部分的简要关系图:

同样的,对于Spring事务,其既然是使用Spring Aop实现的,那么也同样会有这三个成员。我们这里我们只看到了注册的Advisor和Advice(即BeanFactoryTransactionAttributeSourceAdvisor和TransactionInterceptor),那么Pointcut在哪里呢?这里我们查看BeanFactoryTransactionAttributeSourceAdvisor的源码可以发现,其内部声明了一个TransactionAttributeSourcePointcut类型的属性,并且直接在内部进行了实现,这就是我们需要找的Pointcut。这里这三个对象对应的关系如下:

这样,用于实现Spring事务的Advisor,Pointcut以及Advice都已经找到了。关于这三个类的具体作用,我们这里进行整体的上的讲解,后面我们将会深入其内部讲解其是如何进行bean的过滤以及事务逻辑的织入的。
• BeanFactoryTransactionAttributeSourceAdvisor:封装了实现事务所需的所有属性,包括Pointcut,Advice,TransactionManager以及一些其他的在Transactional注解中声明的属性;
• TransactionAttributeSourcePointcut:用于判断哪些bean需要织入当前的事务逻辑。这里可想而知,其判断的基本逻辑就是判断其方法或类声明上有没有使用@Transactional注解,如果使用了就是需要织入事务逻辑的bean;
• TransactionInterceptor:这个bean本质上是一个Advice,其封装了当前需要织入目标bean的切面逻辑,也就是Spring事务是如果借助于数据库事务来实现对目标方法的环绕的。
2.1.7:什么是Spring IOC容器?优点是什么?
IOC 就是控制反转,原来我们需要创建对象的,必须自己 new,但是现在有了 spring 容器,我们不需要再自己 new
了,有两个好处,解耦,因为对象自己 new 完之后,无法更改,如果依赖对象发生异常,则会对我们自己的类造成
影响。
springIOC,用户只需要进行配置,容器会在容器中自动实例化依赖对象,并且是单例模式,直接通过@autowired
直接注入即可。
IOC 主要是通过反射实现,底层原理大概是这样的:
1、项目启动,加载 web.xml;
2、在 web.xml 根据 context-param 通过 contextListener 加载 spring 上下文,
加载 spring 配置文件;
3、我猜,spring 可能通过 dom4j 解析 xml 配置文件;
4、获取 bean 标签,一旦发现 bean 标签,则读取 class 属性;
5、通过反射,Class.forName,获取该类的 class 字节码对象;
6、调用通过 Constructor 的 newInstance()实例化对象;
7、说 IOC 就离不开 DI,所谓 DI 是依赖注入,spring 的依赖注入有两种方式:
构造注入和 setter 注入;
8、所谓构造注入,就是读取标签的,
通过 class 字节码文件对象,获取构造参数;
9、通过 Constructor,直接构造对象,并对依赖对象进行初始化;
10、setter 注入,就是通过反射的;
11、通过 Field,设置依赖对象的属性值,dom4j 读取 property 标签的 name 和 value 属性值,
根据 name 获取 Field 成员,一般来说会通过 setAccessible 暴力破解,然后通过 set 方法,
指定 field 的对象和属性值,完成 setter 注入。
总结:以上就是对于 spring 的 IOC 和 DI 的理解,大概就是通过反射和 dom4j 完成控制反转和依赖注入。
Spring 的 IOC 有三种注入方式 :构造器注入、setter 方法注入、根据注解注入。
2.1.8:什么是Spring的依赖注入?有哪些不同类型的注入方式?
控制反转和依赖注入讲的都是一个概念,只不过是站在了不同的角度,所谓的依赖注入:
是指在运行期,由外部容器动态地将依赖对象注入到组件中。当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它。所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。这种现象就称作控制反转,即应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
spring的IOC有三种注入方式 第一是根据属性注入 也叫set方法注入;第二种是根据构造方法进行注入;第三种是根据注解进行注入;
2.1.9:谈谈什么是aop,应用场景有那些?
Spring MVC处理异常有3种方式:
 使用简单异常处理器SimpleMappingExceptionResolver
这种方式只需要在 SpringMVC 配置文件中注册这个异常处理器 Bean 就行了。这个Bean 比较特殊,没有 id 属性,无需显式调用或被注入给其它,当异常发生时会自动执行该类。我们可以在配置文件里,写一些自定义异常,然后配置好每个异常对应的异常页面,也可以统一配置异常页面。这种方式可以实现发生指定异常后的跳转。
但若要实现在捕获到指定异常时,执行一些操作的目的,它是完成不了的。如果要实现这样的功能,就需要自定义异常处理器
 使用异常处理接口HandlerExceptionResolver 自定义自己的异常处理器
自定义异常处理器,需要实现HandlerExceptionResolver接口,然后重写resolveException方法,并且该类需要在SpringMVC配置文件中进行注册。
这样的话,只要有异常发生,无论什么异常,都会自动执行resolveException接口方法,这样我们就可以在异常发生之后,执行一些其他操作了
 使用@ExceptionHandler注解实现异常处理
@ExceptionHandler这个注解可以让每个方法都有自己的异常处理方式。可以用在方法上,需要给这个注解传入一个异常处理的类,当这个方法抛出异常的时候,会自动执行传入的这个类的方法,从而可以执行我们想要的业务逻辑。当然也可以用在类上,这个类所有方法抛出异常,都会执行响应的业务逻辑。
不过,一般不这样使用。而是将异常处理方法专门定义在一个 Controller 中,让其它Controller 继承这个 Controller 即可。但是,这种用法的弊端也很明显:Java 是“单继承多实现”的,这个 Controller 的继承将这唯一的一个继承机会使用了,使得若再有其它类需要继承,将无法直接实现。
我们项目中使用的都是第二种,使用HandlerExceptionResolver 自定义异常处理器实现的统一异常回复
2.1.10:SpringBean的作用域分别有那些?
tips:控制器就是我们的controller
默认是单例模式的,这会对导致,如果在控制器里写有成员变量,在多线程访问的时候有线程安全问题,所以一般我们在使用的时候,都不会在在类里写成员变量。
这块这么设计,我想着主要有两个原因,一呢是从高性能方面考虑,不需要每次请求都创建对象了,二呢是这个控制器不需要而且也没必要使用多例的
2.1.11:什么是bean的自动装配?
第一种:使用Model或者ModelMap对象,model.addAttribute(“user”,”张三”),前台使用el表达式接收
第二种:使用HttpservletRequest对象,request.setAttribute(“user”,”张三”);前台使用el表达式接收
第三种:使用Map对象,map.put(“user”,”张三”);前台使用el表达式接收
2.1.12: 怎么样把ModelMap里面的数据放入session里面?
可以在类上面加上@SessionAttributes注解,把想要放入session中的字段传给注解,然后ModelMap中的字段会自动放入session中

2.1.13:在SpringAOP中,关注点和横切关注的区别是什么?
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的
一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应
用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些
都属于横切关注点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值