Spring框架介绍
Spring是一个贯穿各层为javaEE提供一站式解决方案的框架,Spring中主要有容器模块,AOP模块,ORM和DAO模块,Web模块等等,具体有以下功能特征。
IOC(或者叫做DI)的核心机制,提供了bean工厂(Spring容器),提高了组件之间的解耦
AOP的将一些通用任务,如安全、事务、日志等集中进行管理,提高了复用性和管理的便捷性
ORM和DAO提供了与第三方持久层框架的良好整合,简化了底层数据访问
提供了优秀的Web MVC框架
ApplicationContext
Spring容器最基本的接口就是BeanFactory,BeanFactory负责配置,创建和管理Bean,这个接口提供getBean()方式直接获取通过容器创建的bean实例。
BeanFactory接口最常用的子接口是ApplicationContext接口,对于大部分J2EE,就是将ApplicationContext的实例作为容器。
ApplicationContext接口最常用的实现类是ClassPathXmlApplicationContext
当系统创建ApplicationContext容器时,默认会初始化所有的singleton Bean,包括调用构造函数创建Bean,并根据配置做依赖注入。因此在系统前期,创建ApplicationContext时将
有交大的系统开销,一旦ApplicationContext初始化完成,后面再获取singleton Bean的时候会得到较好的性能。
Spring国际化
Spring提供的ResourceBundleMessageSource Bean可以读取外部配置文件用来替换国际化代码标签.
Spring创建Bean的3种方式
1.ApplicationContext直接调用Bean的默认构造函数创建Bean实例
2.ApplicationContext调用用静态工厂方法,静态方法中创建Bean实例
3.ApplicationContext先实例化工厂,再创建Bean实例
工厂Bean: FactoryBean接口
- 什么是工厂bean
Spring中的工厂Bean指的是一类特殊的Bean, 必须要实现FactoryBean接口(注意区分BeanFactory),用来生产特定产品。而传统/标准的工厂Bean是不需要实现这个接口的。
- 工厂bean有什么特征
Spring框架中,如果一个普通bean实现了FactoryBean接口,这个Bean就成了一个Spring容器工厂Bean,调用这个工厂Bean的getBean()方法,实际上会执行FactoryBean接口的getObject()方法,
并且将getObject()方法的返回值作为getBean()的结果,而这里的getObject()是由开发者来实现的,开发者希望返回什么就返回什么。
- Spring中有哪些工厂常见工厂Bean
PropertyPathFactoryBean , 用来返回ref指定bean的getter()方法的结果
MethodInvokingFactoryBean, 用来返回ref指定的bean,target指定的方法的结果
FieldRetrivingFactoryBean, 用来获取ref指定bean,target指定的字段值
Bean前行为和Bean后行为
对于单例(singleton)Spring可以精确控制生命周期,因此可以在bean的各个阶段指定各种行为。
在依赖关系注入之后,可以根据bena标签init-method让bena执行指定方法,也可以让bean实现InitialializingBean接口执行afterPropertiesSet()方法。
在bean被销毁之前,可以根据bean标签destory执行指定的方法,也可以让bean实现DisposableBean接口执行destroy()方法。
InitializingBean是针对单个Bean起作用的,Spring还提针对所有Bean的BeanPostProcessor接口,只要实现postProcessBeforeInitialization()和postProcessAfterInitialization(),就能对批量Bean在初始化前后插入特定方法。
同步singleton Bean和prototype Bean
如果在一个singleton类型的bean中注入一个prototype类型的bean时候,会发现有个问题,在整个应用程序生命周期,singleton bean只会被初始化一次,然而prototype bean每次都会重新创建并初始化,那么意味着singleton中的依赖注入并不是最新的。
解决办法就是将singleton类型的bean定义成抽象类,让Spring为其动态生成子类(反射),并重写getter()方法,在getter() 方法中调用 ctx.getBean("目标Bean")就能保证每次都是获取最新的prototype bean了。
Resource接口和ResourceLoader
Spring提供了一个Resource接口用来访问资源,其底层是封装了各种各种资源的访问方式,例如网络资源,本地资源,二进制数据等等,
通过Resource实现类的对象,可以对资源进行统一方式的操作,还可以通过Rescource实现类的对象获取资源的File实例,以java IO的方式操作资源。
Resource提供如下对资源的统一访问方法:getInputStream(), exists(), isOpen(), getDescription(), getFile(), getUrl()。
Spring为Resource默认已经实现了如下类:UrlResource, ClassPathResource, FileSystemResource, ServletContextResource, InputStreamResource, ByteArrayResource.
ResourceLoader接口的getResource(...)方法可以获取一个Resource的实例,而ApplicationContext也实现了ResourceLoader接口,
因此可以直接使用ctx.getResource(...)获取一个Resource实例,ApplicationContext会作为一个观察者,根据ApplicationContext的实现类型来决定选择Resource的哪个实现类,开发人员只需要面向接口编程,这是典型的观察者模式。
1 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans2.xml"); 2 //ApplicationContext ctx = new FileSystemXmlApplicationContext("beans2.xml"); 3 Resource res =ctx.getResource("beans2.xml");
上面是Spring的观察者模式获取Resource的代码,只需要面向接口编程,根据第1行和第2行选择的不同的ApplicationContext实现类,第3行就会获取对应的Resource实现类,这底层都由Spring处理了。
比ResourceLoader更能解耦的方式是直接将Resource的实例作为Bean的属性,这样就能直接在XML文件中配置需要访问的资源名称。
Spring AOP
Sping AOP默认使用Java JDK动态代理来创建AOP代理,因为Spring推荐的是面向接口的编程。当然也可以强制使用cglib进行动态代理。
Aspect是在类加载器层面进行编译增强,从而实现AOP,需要用特定的编译方法。Spring AOP可以使用根AspectJ一样的注解语法,但是底层依然使用Spring AOP实现的,不依赖于Aspect的编译器或者织入器。
常用增强处理有Beore,AfterRunning,AfterThrowing,After,Around等。
AfterRunning可以为Advice(增强方法)设置的形参指定一个数据类型,这个切面类只会匹配与形惨类型相同的返回值的方法。
AfterThrowing则可以为Advice(增强方法)设置的形参指定一个数据类型,这个切面类需要匹配抛出与形参类型相同的异常的方法。
After与Afterreturning的区别,Afterreturning只有在目标方法成功完成之后才会被织入,但是After无论目标方法正常结束还是遇到异常,都能织入增强处理。After就相当于finally{}代码块。
Around增强处理类似于Before增强和AfterReturning增强处理的总和,但是更强大。Around增强处理不仅可以随意控制目标方法的执行时机,还能修改方法的参数和返回值。
JoinPoint类的实例可以作为Before, Around, AfterReturning, After增强的Advice方法的参数,用来访问目标方法的参数