开源框架专栏
1.TOMCAT性能优化整理
2.JVM性能优化整理
3.MYSQL性能优化整理
4.并发编程整理(1)
5.并发编程整理(2)
6.spring(1)
7.spring(2)
文章目录
- 开源框架专栏
- spring
- 23、Spring 框架中有哪些不同类型的事件?
- 24、FileSystemResource 和ClassPathResource有何区别?
- 25、Spring 中使⽤用了哪些设计模式?
- 26、开发中主要使用Spring的什么技术?
- 27、简述AOP和IOC概念
- 28、在Spring中如何配置Bean ?
- 29、IOC容器对Bean的生命周期:
- 30、AOP源码分析
- 31、AOP 核⼼概念
- 32、AOP使⽤用哪种动态代理?
- 33、jdk动态代理
- 34、CGLIB动态代理
- 35、何时使用JDK还是CGLIB?
- 36、如何强制使用CGLIB实现AOP?
- 37、JDK动态代理和CGLIB字节码生成的区别?
- 38、CGlib比JDK快?
- 39、Spring如何选择用JDK还是CGLIB?
- 40、Spring框架的七⼤大模块
- 41、spring ioc初始化流程?
- 42、 BeanDefinition加载流程?
- 43、DI依赖注⼊流程? (实例例化,处理理Bean之间的依赖关系)
- 44、依赖注入怎么处理bean之间的依赖关系?
spring
23、Spring 框架中有哪些不同类型的事件?
Spring的ApplicationContext提供了支持事件和代码中监听器的功能。我们可以创建bean用来监听在ApplicationContext中发布的事件。ApplicationEvent类和在ApplicationContext接口中处理的事件,如果一个bean实现了ApplicationListener 接口,当一 个ApplicationEvent被发布以后,bean会自动被通知。
public class AllApplicationEventListener implements ApplicationListener<ApplicationEvent>{
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent){
//process event
}
}
Spring提供了以下5中标准的事件:
- 上下文更新事件(ContextRefreshedEvent:该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext接口中的refresh0方法时被触发。
- 上下文开始事件(ContextStartedEvent:当容器调用ConfigurableApplicationContext的Start0方法开始/重新开始容器时触发该事件。
- 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的 Stop(方法停止容器时触发该事件。
- 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
- 请求处理事件(RequestHandledEvent):在Web应用中, 当一个http请求(request)结束 触发该事件。
除了上面介绍的事件以外,还可以通过扩展ApplicationEvent 类来开发自定义的事件。
public class CustomApplicationEvent extends ApplicationEvent{
public CustomApplicationEvent ( Object source, final String msg ){
super(source);
System.out.println("Created a Custom event");
}
}
为了监听这个事件,还需要创建一个监听器:
public class CustomEventListener implements ApplicationListener<CustomApplicationEvent >{
@Override
public void onApplicationEvent(CustomApplicationEvent applicationEvent) {
//handle event
}
}
之后通过applicationContext 接口的publishEvent()方法来发布自定义事件。
CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, "Test message");
applicationContext.publishEvent(customEvent);
24、FileSystemResource 和ClassPathResource有何区别?
在FileSystemResource中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource文件放在ClassPath
下。
如果将spring-config.xml保存在了src 文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。
简而言之,ClassPathResource 在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
25、Spring 中使⽤用了哪些设计模式?
- 工厂模式:spring中的BeanFactory就是简单⼯厂模式的体现,根据传⼊唯⼀的标识来获得bean对象;
- 单例例模式:提供了全局的访问点BeanFactory;
- 代理模式:AOP功能的原理就使⽤代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)
- 装饰器器模式:依赖注入就需要使⽤BeanWrapper;
- 观察者模式:spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
- 策略略模式:Bean的实例化的时候决定采用何种方式初始化bean实例(反射或者CGLIB动态字节码⽣生成)
26、开发中主要使用Spring的什么技术?
- IOC容器管理各层的组件
- 使用AOP配置声明式事务
- 整合其他框架.
27、简述AOP和IOC概念
AOP: Aspect Oriented Program,面向(方面)切面的编程:;ilter(过滤器)也是-种AOP. AOP是-种新的方法论,是对传统OOP(Object-Oriented Programming,面向对象编程)的补充. AOP的主要编程对象是切面(aspect),而切面模块化横切关注点.可以举例通过事务说明.
IOC: Invert Of Control,控制反转.也成为DI(依赖注入)其思想是反转资源获取的方向.传统的资源查找方式要求组件向容器发起请求查找资源.作为回应,容器适时的返回资源.而应用了IOC之后,则是容器主动地将资源推送
给它所管理的组件,组件所要做的仅是选择一 种合适的方式来接受资源.这种行为也被称为查找的被动形式
28、在Spring中如何配置Bean ?
Bean的配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法&实例工厂方法)、FactoryBean
29、IOC容器对Bean的生命周期:
- 通过构造器或工厂方法创建Bean实例
- 为Bean的属性设置值和对其他Bean的引用
- 将Bean实例传递给Bean前置处理器的postProcessBeforelnitialization方法
- 调用Bean的初始化方法init-method)
- 将Bean实例传递给Bean后置处理器的postProcessAfterlnitialization方法
- Bean可以使用了
- 当容器关闭时,调用Bean的销毁方法(destroy-method)
30、AOP源码分析
- @EnableAspectJAutoProxy给容器器(beanFactory)中注册⼀个AnnotationAwareAspectJAutoProxyCreator对象;
- AnnotationAwareAspectJAutoProxyCreator对⽬标对象进⾏代理对象的创建,对象内部,是封装JDK和CGlib两个技术,实现动态代理对象创建的(创建代理 对象过程中,会先创建⼀个代理⼯厂,获取到所有的增强器(通知方法),将这些增强器和⽬标类注⼊代理⼯厂,再⽤代理工厂创建对象);
- 代理理对象执⾏⽬标方法,得到⽬标⽅法的拦截器链,利用拦截器的链式机制, 依次进⼊每一个拦截器进行执⾏
31、AOP 核⼼概念
- 切⾯面(aspect):类是对物体特征的抽象,切⾯就是对横切关注点的抽象
- 横切关注点:对哪些⽅法进行拦截,拦截后怎么处理,这些关注点称之为横切关
注点。 - 连接点(joinpoint):被拦截到的点,因为 Spring 只⽀持⽅法类型的连接点, 所以在Spring 中连接点指的就是被拦截到的⽅法,实际上连接点还可以是字段或者 构造器器。
- 切入点(pointcut):对连接点进⾏行行拦截的定义
- 通知(advice):所谓通知指的就是指拦截到连接点之后要执⾏的代码,通知分为前置、后置、异常、最终、环绕通知五类。
- ⽬目标对象:代理理的⽬目标对象
- 织入(weave):将切面应⽤到目标对象并导致代理对象创建的过程
- 引入(introduction):在不修改代码的前提下,引⼊可以在运行期为类动态地添加方法或字段。
32、AOP使⽤用哪种动态代理?
当bean的是实现中存在接口或者是Proxy的子类,jdk动态代理;不存在接⼝,spring会采⽤CGLIB来⽣成代理对象;
JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和InvocationHandler。
Proxy利用InvocationHandler(定义横切逻辑) 接⼝动态创建 ⽬标类的代理对象。
33、jdk动态代理
通过bind⽅法建⽴代理与真实对象关系,通过Proxy.newProxyInstance(target)⽣成代理对象 代理对象通过反射invoke⽅法实现调用真实对象的方法
34、CGLIB动态代理
利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
35、何时使用JDK还是CGLIB?
- 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
- 如果目标对象实现了接口,可以强制使用CGLIB实现AOP。
- 如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。
36、如何强制使用CGLIB实现AOP?
-
添加CGLIB库(aspectjrt-xxx.jar、aspectjweaver-xxx.jar、cglib-nodep-xxx.jar)
-
在Spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>
37、JDK动态代理和CGLIB字节码生成的区别?
-
JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
-
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,对于final类或方法,是无法继承的。
38、CGlib比JDK快?
-
使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在jdk6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
-
在jdk6、jdk7、jdk8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLIB代理效率,只有当进行大量调用的时候,jdk6和jdk7比CGLIB代理效率低一点,但是到jdk8的时候,jdk代理效率高于CGLIB代理,总之,每一次jdk版本升级,jdk代理效率都得到提升,而CGLIB代理消息确有点跟不上步伐。
39、Spring如何选择用JDK还是CGLIB?
- 当Bean实现接口时,Spring就会用JDK的动态代理。
- 当Bean没有实现接口时,Spring使用CGlib是实现。
- 可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>)。
40、Spring框架的七⼤大模块
- Spring Core:框架的最基础部分,提供 IoC 容器器,对 bean 进行管理。
- Spring Context:继承BeanFactory,提供上下⽂信息,扩展出JNDI、EJB、电⼦邮件、国际化等功能。
- Spring DAO:提供了JDBC的抽象层,还提供了了声明性事务管理方法。
- Spring ORM:提供了JPA、JDO、Hibernate、MyBatis 等ORM映射层.
- Spring AOP:集成了所有AOP功能
- Spring Web:提供了基础的 Web 开发的上下文信息,现有的Web框架,如JSF、 Tapestry、Structs等,提供了集成
- Spring Web MVC:提供了 Web 应⽤的Model-View-Controller 全功能实现
41、spring ioc初始化流程?
resource定位 即寻找⽤户定义的bean资源,由 ResourceLoader通过统一的接口 Resource接口来完成 beanDefinition载入 BeanDefinitionReader读取、解析 Resource定位的资源 成BeanDefinition 载入到ioc中(通过HashMap进⾏行行维护BD)
BeanDefinition注册 即向IOC容器器注册这些BeanDefinition,通过 BeanDefinitionRegistery实现
42、 BeanDefinition加载流程?
定义BeanDefinitionReader解析xml的document BeanDefinitionDocumentReader 解析document成beanDefinition
43、DI依赖注⼊流程? (实例例化,处理理Bean之间的依赖关系)
过程在Ioc初始化后,依赖注⼊的过程是⽤用户第一次向IoC容器器索要Bean时触发
- 如果设置lazy-init=true,会在第⼀次getBean的时候才初始化bean,lazy-init=false,会容器器启动的时候直接初始化(singleton bean);
- 调⽤用BeanFactory.getBean()生成bean的;
- 生成bean过程运⽤用装饰器模式产生的bean都是beanWrapper(bean的增强);
44、依赖注入怎么处理bean之间的依赖关系?
其实就是通过在beanDefinition载⼊时,如果bean有依赖关系,通过占位符来代 替,在调用getbean时候,如果遇到占位符,从ioc⾥里里获取bean注入到本实例来