开源框架专栏-spring(2)

开源框架专栏

1.TOMCAT性能优化整理
2.JVM性能优化整理
3.MYSQL性能优化整理
4.并发编程整理(1)
5.并发编程整理(2)
6.spring(1)
7.spring(2)



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中标准的事件:

  1. 上下文更新事件(ContextRefreshedEvent:该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext接口中的refresh0方法时被触发。
  2. 上下文开始事件(ContextStartedEvent:当容器调用ConfigurableApplicationContext的Start0方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的 Stop(方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(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的什么技术?

  1. IOC容器管理各层的组件
  2. 使用AOP配置声明式事务
  3. 整合其他框架.

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的生命周期:

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

30、AOP源码分析

  • @EnableAspectJAutoProxy给容器器(beanFactory)中注册⼀个AnnotationAwareAspectJAutoProxyCreator对象;
  • AnnotationAwareAspectJAutoProxyCreator对⽬标对象进⾏代理对象的创建,对象内部,是封装JDK和CGlib两个技术,实现动态代理对象创建的(创建代理 对象过程中,会先创建⼀个代理⼯厂,获取到所有的增强器(通知方法),将这些增强器和⽬标类注⼊代理⼯厂,再⽤代理工厂创建对象);
  • 代理理对象执⾏⽬标方法,得到⽬标⽅法的拦截器链,利用拦截器的链式机制, 依次进⼊每一个拦截器进行执⾏

31、AOP 核⼼概念

  1. 切⾯面(aspect):类是对物体特征的抽象,切⾯就是对横切关注点的抽象
  2. 横切关注点:对哪些⽅法进行拦截,拦截后怎么处理,这些关注点称之为横切关
    注点。
  3. 连接点(joinpoint):被拦截到的点,因为 Spring 只⽀持⽅法类型的连接点, 所以在Spring 中连接点指的就是被拦截到的⽅法,实际上连接点还可以是字段或者 构造器器。
  4. 切入点(pointcut):对连接点进⾏行行拦截的定义
  5. 通知(advice):所谓通知指的就是指拦截到连接点之后要执⾏的代码,通知分为前置、后置、异常、最终、环绕通知五类。
  6. ⽬目标对象:代理理的⽬目标对象
  7. 织入(weave):将切面应⽤到目标对象并导致代理对象创建的过程
  8. 引入(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?

  1. 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
  2. 如果目标对象实现了接口,可以强制使用CGLIB实现AOP。
  3. 如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。

36、如何强制使用CGLIB实现AOP?

  1. 添加CGLIB库(aspectjrt-xxx.jar、aspectjweaver-xxx.jar、cglib-nodep-xxx.jar)

  2. 在Spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>

37、JDK动态代理和CGLIB字节码生成的区别?

  1. JDK动态代理只能对实现了接口的类生成代理,而不能针对类。

  2. CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,对于final类或方法,是无法继承的。

38、CGlib比JDK快?

  1. 使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在jdk6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

  2. 在jdk6、jdk7、jdk8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLIB代理效率,只有当进行大量调用的时候,jdk6和jdk7比CGLIB代理效率低一点,但是到jdk8的时候,jdk代理效率高于CGLIB代理,总之,每一次jdk版本升级,jdk代理效率都得到提升,而CGLIB代理消息确有点跟不上步伐。

39、Spring如何选择用JDK还是CGLIB?

  1. 当Bean实现接口时,Spring就会用JDK的动态代理。
  2. 当Bean没有实现接口时,Spring使用CGlib是实现。
  3. 可以强制使用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注入到本实例来

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值