33.spring是什么?
轻量级开源的j2EE框架,是一个容器框架,用于装javabean(java对象),中间层框架(万能胶)可以起到一个连接作用,比如把Struts与hibernate粘合在一起运用,可以让企业开发更快更简洁。
Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。
35.面向切面编程(AOP)
(1)AOP介绍:
面向切面编程(AOP)是一种编程范式,旨在通过将横切关注点(例如日志记录、事务管理、安全性等)与业务逻辑分离来提高代码的模块化。AOP是OOP(面向对象编程)的一个补充,它允许开发者以声明方式实现关注点,而不是通过在业务逻辑代码中散布大量重复代码。
(2)AOP核心概念:
切面(ASPECT): 横切关注点被模块化的特殊对象。即,它是一个类。
通知(Advice) : 切面必须要完成的工作。即,它是类中的一个方法。
目标对象(Target)︰被通知对象,被代理的对象,即包含连接点的对象。
代理(Proxy): 向目标对象应用通知之后创建的对象,它负责在执行目标对象的方法前后处理横切关注点。
切入点(PointCut): 切面通知执行的“地点"的定义。
连接点(JointPoint) : 与切入点匹配的执行点。
补充:
切入点:切入点定义那些连接点将被切面所切入,它是一个表达式,用于匹配特定方法执行点。
通知:通知是切面中代码,它定义了切入点所需要执行的动作,通常有以下几种类型:
- 前置通知(Before):在方法执行前执行。
- 后置通知(After):在方法执行后执行。
- 返回通知(After Returning):在方法成功返回后执行。
- 异常通知(After Throwing):在方法抛出异常后执行。
- 环绕通知(Around):包围方法执行的前后。
(3)AOP的优势:
- 减少代码重复:可以将横切关注点集中管理,有效的减少代码重复;
- 提高模块化:将业务逻辑与非业务逻辑分离,提高代码清晰度和可维护性;
- 易于维护更新:当需要修改横切关注点时候,只需要在一个地方进行修改。
(4)AOP的实现方式:
- 编译时增强:在编译时候通过修改字节码实现AOP;
- 类加载时增强:在类加载到JVM时候通过字节码操作实现AOP;
- 动态代理:程序运行时候通过代理对象来实现AOP。
Spring AOP实现:
- 基于接口代理:只能为实现了接口的Bean创建代理。
- 基于类的代理:可以为所有类创建代理。
实际上,AOP的底层是通过Spring提供的动态代理技术实现的,在运行期间,Spring通过动态代理的技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
(5)AOP实际应用:
1)日志记录
AOP可以用于在不修改业务逻辑代码情况下,实现日志记录功能。
2)事务代理
AOP 可以用于声明式事务管理,通过在方法执行前后添加事务的开启和关闭。
- 安全性控制
AOP 可以用于实现安全性控制,如权限验证。
36.对IOC的理解
核心点:容器概念,控制反转,依赖注入
IOC容器概念:
实际上是一个map(key,value),里面存着是各种对象(在xml里面配置的bean节点,@repository,@service,@controller,@component),在项目启动的时候会读取配置文件里面的bean节点,或者扫描出来,创建实例并放置到类当中。
这时候map有各种对象,接下来我们在代码中还需要使用到里面对象,还需要对这些对象的属性进行赋值,即通过DI注入【DI注入:依赖注入】(autowired, resource等注释,xml里面bean节点内ref属性, 项目启动时候会读取xml节点ref属性根据id注入,也会扫描这些注释,根据类型注释或者id注入;id就是对象名)
控制反转:
在没有引入IOC容器前,如果A对象依赖于B(即对象A中需要使用到对象B),会在对象A初始化或者运行到某一个点时候,自己主动去创建(new)对象B或者使用已经创建的对象B,无论是创建还是使用对象B,控制权都在自己手里。
但是在引入IOC容器后,如果A对象依赖于B,则IOC容器会主动创建一个对象B注入到对象A需要使用对象B的地方上。
故而,获得依赖对象过程被反转,从主动行为变成被动行为,控制权被颠倒。
依赖注入:
依赖注入是实现IOC的一个方法,由于控制反转,IOC容器在运行期间,会动态的将某种依赖关系注入到对象之中。
11.如何实现一个IOC容器
1.写一个配置文件,配置文件配置包扫描路径
2.递归包扫描获取.Class文件
3.反射,确定需要交给IOC管理的类
4.对需要注入的类进行依赖注入
37.BeanFactory和ApplicationContext区别?
ApplicationContext是BeanFactory的子接口,ApplicationContext提供更完整的功能
(1)继承MessageSource,所以支持国际化。
(2)统一资源文件访问方式。
(3)提供在监听器中注册bean的事件。
(4)同时加载多个配置文件。
(5)载入多个(有继承关系的)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
1.由于BeanFactory采用延迟加载形式注入Bean,所以只有在使用到某个Bean时候(调用getBean()),才对该Bean进行加载实例化。这样,就不能发现一些存在的Spring配置问题,如果Bean的某一个属性没有注入,BeanFactory加载后,直到第一次使用getBean方法时候才会抛出异常。
2.ApplicationContext是在容器启动时候,一次性创建所有Bean。这样,在容器启动时候就会发现Spring中存在的配置错误问题,这样有利于检查依赖是否注入。
(类似于单例模式下的懒汉模式与饿汉模式)
3.相对基于BeanFactory,ApplicationContext唯一不足地方是占用内存空间。当应用程序配置较多Bean时候,程序启动较慢。
4.BeanFactory通常以编程方式创建,而ApplicationContext除了可以使用编程方式创建外还可以使用声明方式创建(如使用ContextLoader)。
5.BeanFactory和ApplicationContext都支持BeanPostProcessor,BeanFactoryPostProcessor的使用,但是二者区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。