Spring最重要的部分之一就是提供了IoC容器,为何须要IoC容器呢?IoC是依赖倒置,或者说是控制反转的意思,控制反转这个词也许咱们耳朵已经听出茧子了,也正是由于如此,也阻碍了咱们从新思考这个词。java
如今,咱们从新思考一下什么是"控制反转"?咱们不下定义,咱们就结合业务场景来思考,例如,咱们的web应用,在Controller层会依赖Service层的逻辑,不一样的Controller可能会依赖相同的service层对象。例如,库存和积分的Controller都会依赖用户的Service。web
若是没有Spring,咱们常见的作法是在每个Controller中都建立用户的Service,这些建立逻辑可能比较复杂。spring
这样带来的问题就是,建立对象的逻辑分散的处处都是,每一地方都会建立新的对象。springboot
Spring怎么解决这个问题的呢?使用IoC容器。依赖倒置提如今什么地方?原来是Controller依赖Service,如今不依赖了么?不是,不过控制权转移了,都是有Spring来管理,Spring建立对象,而后注入到须要的对象之中。mvc
这样的好处是显而易见的,建立逻辑都不用咱们管了,依赖对象也不用咱们关心了,不少对象能够共享,不用重复建立、销毁。app
BeanDefinition解析有2个重要的接口,它们分别是BeanDefinitionReader和BeanDefinitionParser。ide
BeanDefinitionReader的做用是读取bean的信息,例如,BeanDefinitionReader的间接实现类XmlBeanDefinitionReader就是从xml文件中读取bean的信息。ui
读取到bean信息了,还须要把这些信息解析为BeanDefinition,这个过程是BeanDefinitionParser的职责,例如,AnnotationDrivenBeanDefinitionParser就是从注解中解析BeanDefinition。this
在实际的解析中可能具体的解析类是其余的,例如XmlBeanDefinitionReader,实际注册是利用BeanDefinitionDocumentReader接口的实现类DefaultBeanDefinitionDocumentReader。spa
DefaultBeanDefinitionDocumentReader实际上只处理了一些标签,例如beans、alias、name、import、resource、profile等。
像常见的标签bean、ref等标签实际是BeanDefinitionParserDelegate处理的,BeanDefinitionParserDelegate也不会处理所有标签。
BeanDefinitionParserDelegate会经过NamespaceHandler来处理一些自定义标签,像下面的标签都是经过对应的NamespaceHandler实现类来处理的。
<tx:annotation-driven/> <tx:advice id="txAdvice" transaction-manager="myTracnsactionManager"> <aop:config> <dubbo:reference id="xxxService" interface="xxx.XxxService"/> <context:annotation-config /> <mvc:interceptors>
NamespaceHandler会经过NamespaceHandlerSupport来找到一个合适的BeanDefinitionParser,而后经过BeanDefinitionParser的parse方法来解析出对应的BeanDefinition。
有了BeanDefinition,怎样经过BeanDefinition建立真正的bean的呢?
BeanFactoryPostProcessor
BeanPostProcessor
BeanFactoryAware
BeanNameAware
InitializingBean
DisposableBean
InstantiationAwareBeanPostProcessorAdapter
InstantiationAwareBeanPostProcessor
按照类型匹配,默认必须找到,找不到就抛异常,若是不是必须,能够设置require=false。这个和经过xml配置autowire属性(也就是@Bean的autowire属性。)差很少。
不过xml方式autowire必须有setter方法,而@Autowired能够不用setter方法,而且@Autowired只有经过type注入,要经过name方式还得多加一个@Qualifier("name")注解。
@Autowired的注解处理器是AutowiredAnnotationBeanPostProcessor。
在AbstractAutowireCapableBeanFactory中有一个ignoreDependencyInterface方法,能够设置不容许setter注入,这个主要是为了不一些特殊的类被随意注入了,例如ApplicationContext、BeanFactory等。这样要获取ApplicationContext必须实现ApplicationContextAware,而不只仅是在类中添加一个ApplicationContext属性就能够了。
最先的数据类型转换是使用的PropertyEditor,支持的是String和Object之间的转换,在Spring中主要用在2个地方。
通常不会直接实现PropertyEditor接口,而是直接继承PropertyEditorSupport类。
PropertyEditor是经过org.springframework.beans.factory.config.CustomEditorConfigurer注册的。也能够实现PropertyEditorRegistrar,而后将PropertyEditorRegistrar设置到CustomEditorConfigurer中。
注意PropertyEditorRegistry和PropertyEditorRegistrar,Registry是登记处,Registrar是以ar结尾,表示登记员的意思。因此顾名思义PropertyEditorRegistry是注册PropertyEditor的地方,PropertyEditorRegistrar的做用是把PropertyEditor注册到本身管理的PropertyEditorRegistry中。
Spring 3开始增长了一个Converter接口,能够完成任意2个类型之间的转换,这点比PropertyEditor强,PropertyEditor只能是String与Object之间的转换。
Converter的通常玩法是,实现ConverterFactory接口,在实现类中给一个静态内部类实现Converter。ConverterFactory的getConverter返回这个Converter就能够了。
若是是更加复杂的转换能够考虑GenericConverter和ConditionalConverter接口。
ConversionService接口为类型转换提供统一转换API来执行运行时的转换逻辑,使用的是外观模式(facade)。配置ConversionService只须要配置一个id为conversionService的org.springframework.context.support.ConversionServiceFactoryBean就能够了。自定义的Converter也能够经过ConversionServiceFactoryBean设置。
org.springframework.format.Formatter接口和PropertyEditor接口差很少,不过结构更加清晰,PropertyEditor接口有不少GUI相关的方法,而Spring的Formatter接口,就是继承了从类型T到String的Printer接口和从String到类型T的Parser接口。
注解驱动的Formatter能够实现AnnotationFormatterFactory提供支持,Formatter也有registry和registrar,它们分别是FormatterRegistry和FormatterRegistrar。
Spring MVC的AnnotationDrivenBeanDefinitionParser中若是,若是包含“conversion-service”就会注册一个FormattingConversionServiceFactoryBean,FormattingConversionServiceFactoryBean持有一个FormattingConversionService。
mvc中的数据转换是HttpInputMessage、HttpOutputMessage和Java数据类型之间的转换,实现HttpMessageConverter接口就能够了。
咱们知道MVC中有2个重要的接口一个是HandlerAdapter,另外一个是HandlerMapping。简化点说HandlerMapping作的事情就是把请求URL找到对应的method来处理。HandlerAdapter看名字有点像适配器模式,实际上更像是代理模式。
HandlerAdapter的做用就是处理一些公共的逻辑,例如解析@RequestParam、@PathVariable、@RequestBody、@ResponseBody等注解...
想想HTTP协议或者直接经过Servlet处理须要处理的逻辑,再对比一下咱们使用@Controller和@RequestMapping注解以后的方法的逻辑,就知道HandlerAdapter作了多少事情了。正是由于如此、HandlerAdapter的能够定制的程度也高。
如今spring mvc中默认使用的HandlerAdapter和HandlerMapping是: RequestMappingHandlerAdapter RequestMappingHandlerMapping 这2个类是在DispatcherServlet.properties配置的。
使用http://www.javashuo.com/tag/mvc:annotation-driven标签,默认注册的也是这2个类,前面已经介绍了这种标签的解析,感兴趣能够本身查看一下MvcNamespaceHandler和AnnotationDrivenBeanDefinitionParser这2个类,NamespaceHandler是在META-INF的spring.handler中配置的,自定义NamespaceHandler的时候注意建立对应的xsd和spring.handler文件。
spring mvc中处理参数和返回值的主要接口和类:
HandlerMethodReturnValueHandlerComposite HandlerMethodReturnValueHandler HandlerMethodArgumentResolverComposite HandlerMethodArgumentResolver
典型的组合模式,不过Composite中采用的不是遍历,而是找到第一个支持的Handler来处理。 看RequestMappingHandlerAdapter源码中有下面2个方法,用来初始化默认的HandlerMethodReturnValueHandler和HandlerMethodArgumentResolver。
RequestMappingHandlerAdapter#getDefaultArgumentResolvers RequestMappingHandlerAdapter#getDefaultReturnValueHandlers
还有一个HttpMessageConverter集合,是用来给RequestResponseBodyMethodProcessor、RequestPartMethodArgumentResolver、HttpEntityMethodProcessor、ResponseBodyEmitterReturnValueHandler这几个参数返回值处理器使用的。@ResponseBody和@RequestBody很是常见,通常咱们知道出问题是在什么地方,可是当参数和返回值是HttpEntity的时候,也会使用到HttpMessageConverter,这个须要注意,例如,使用HttpEntity做为返回值传输文件,就得看一下有没有配置ByteArrayHttpMessageConverter这个转换器。
BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。
FactoryBean,以Bean结尾,表示它是一个Bean,不一样于普通Bean的是它实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的其实是FactoryBean的getObject()返回的对象,而不是FactoryBean自己,若是要获取FactoryBean对象,请在id前面加一个&符号来获取。
Environment主要是读取系统变量和属性,固然也会出来classpath或者指定路径下的properties文件,主要涉及的类有:
@PropertySource({"classpath:base.properties"}) @Component public class BaseBean { @Value("${host:127.0.0.1}") private String host; @Value("${base.host:127.0.0.1}") private String baseHost; @Value("#{'Hello World'.concat('!')}") private String helloWorld; @Value("#{'${base.server.name}'.split(',')}") private List<String> servers; public String getHost() { return host; } public void setHost(String host) { this.host = host; } public String getBaseHost() { return baseHost; } public void setBaseHost(String baseHost) { this.baseHost = baseHost; } public String getHelloWorld() { return helloWorld; } public void setHelloWorld(String helloWorld) { this.helloWorld = helloWorld; } public List<String> getServers() { return servers; } public void setServers(List<String> servers) { this.servers = servers; } @Override public String toString() { return "BaseBean{" + "host='" + host + '\'' + ", baseHost='" + baseHost + '\'' + ", helloWorld='" + helloWorld + '\'' + ", servers=" + servers + '}'; } }
@ConfigurationProperties是springboot的中的,不能和@Value同时使用,只须要使用一个就能够了。