spring boot自动化配置原理

spring-cloud其他文章:
我们有必要花时间了解spring boot吗?
spring boot集成ActiveMQ
spring-cloud中eureka进行服务治理

概述

spring boot系列(第一篇):我们有必要花时间了解spring boot吗?

spring boot好用,原因在于省去了很多繁杂的配置。一般开发服务端项目需要的服务、数据库、事务、缓存、消息、作业、访问控制,这些模块的基础配置,spring boot都给我们配置好了。

需要哪个模块,我们要做可能就是简单的几项操作:添加对应的starter依赖;在application.properties文件添加url、端口、线程数、队列名称等属性值;添加@Enablexxx注解。

spring boot流行的原因也是在于它的简单、快速,恰好贴合了当前主流的敏捷、快速迭代的需求,给微服务化带来了很多便利。

spring boot的优点不仅仅是自动化配置,还有它的actuator提供的生产环境运维支持,打包成单个jar支持,上云支持。这些内置的支持,让java服务开发变得简单、快速、专业、易于维护。

注解orXML?

spring boot官方是主张完全用注解替代XML的。那么实际生产环境下,我们该用注解还是该用XML,哪里用注解,哪里用XML?

在stackoverflow上有一个讨论,可以看这里.

大意是说,应该结合使用annotation和XML,但遇到依赖注入的类时,被依赖的对象应该使用XML配置。这样,当需要修改实现类的时候,能够不修改代码、不重新打包完成更换。

对于生产环境,一般来说很少直接线上切换不同的实现类,换也是线下随着某一个版本的发布,完成替换。

有一点需要注意的是,对于上述提到的被依赖接口的实现类最好在单独的位置去注解,不要直接在类上注解@Component、@Repositry、@Service。建议,当一个类的实例被其他类依赖时,在一个@Configuration注解的类里面,用@Bean去注解需要实例化的类,@Configuration和@Bean是spring 3.0之后开始支持的一组新注解,从而可以支持完全无XML配置。如下形式:

package com.dangdang.cart_test.configuration.web;

import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfiguration {

    @Bean
    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean
    public IBookService bookService(){
        return new MyBookService();
    }

}

而不要直接在实现类上注解,不要像这样:

package com.dangdang.cart_test.configuration.web;

import org.springframework.stereotype.Service;

@Service
public class MyBookService implements IBookService{

}

相对于spring来说,spring boot要年轻不少。现实情况下,公司的项目很多配置都是XML配置的,这时候估计绝大多数人不会想着全部改成Annotation配置的。

对于这种情况,可以沿用XML配置,也可以对新的类用Annotation注解。Annotation和XML同时存在。

spring boot的自动注解做了什么

spring mvc项目最基础的配置需要

看一下常规的spring mvc 项目,需要web.xml配置DispatcherServlet、CharacterEncodingFilter、ContextLoaderListener:

    
    <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring/**/*.xml,classpath:*.xmlparam-value>
    context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>
    
    <filter>
        <filter-name>encodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <async-supported>trueasync-supported>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>encodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

    
    <servlet>
        <servlet-name>SpringMVCservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:spring/appconfig/spring-mvc.xmlparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
        <async-supported>trueasync-supported>
    servlet>
    <servlet-mapping>
        <servlet-name>SpringMVCservlet-name>
        <url-pattern>/*url-pattern>
    servlet-mapping>  

还需要在spring mvc上下文配置文件中,配置MethodHandler、ViewResolver:

    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    bean>

spring boot mvc项目配置需要

pom.xml引入starter-web的jar包:

        <dependency>
                    <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
        dependency>

application.properties中配置viewresolver的属性:

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp

spring boot做了什么

1.自动创建常规的配置项DispatcherServlet、CharacterEncodingFilter、ContextLoaderListener、viewresolver;

2.需要配置的属性,统一在properties文件里面以spring.mvc.xxx格式的属性名配置;

自动注解实现

spring boot为每一个支持的技术(quartz、cache、batch、activemq)都提供了一个starter。引入的一个starter,就对应的引入了这项技术依赖的所有jar文件。

1.比如quzrtz的starter:

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-context-supportartifactId>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-txartifactId>
        dependency>
        <dependency>
            <groupId>org.quartz-schedulergroupId>
            <artifactId>quartzartifactId>
        dependency>
    dependencies>

2.每一个技术还对应了一个autoconfigure,用来当满足某个条件时(一般是某个类存在 && 某个对象不存在),自动实例化需要的对象,比如:

@Configuration
@ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class,
        PlatformTransactionManager.class })
@EnableConfigurationProperties(QuartzProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class })
public class QuartzAutoConfiguration {
    //省略细节的初始化代码
}

这里的@ConditionalOnClass,指定当Scheduler.class, SchedulerFactoryBean.class,PlatformTransactionManager.class (都是quartz的初始化需要的类)都存在时,执行初始化。

@AutoConfigureAfter指定,如果存在DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class配置的话,先执行他们内部的配置代码。

定义一个自动注解

定义一个自定义注解,和spring boot提供的注解一般会有一个小的差别,就是自定义starter的pom.xml会引入自定义的configure项目,这样使用的时候,就可以少引入一个dependency了。或者干脆放到一个autoconfigure工程里面。

github上有一个比较完整、详细的实例,可以参见

备注参考:

spirng boot autoconfigure-徐敏博客:https://my.oschina.net/smartsales/blog/775550
自定义自动配置–github示例项目:https://github.com/snicoll-demos/spring-boot-master-auto-configuration
@Configuration如何使用–官方javadoc(比任何博文都全面完整):https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html
maven pom文件中的optional作用:http://blog.csdn.net/ado1986/article/details/39547839
@configuration无法注入的一个问题(建议不要像文章那样,而是最好使用@PropertySource):http://www.coderli.com/spring-configuration-autowire-failed/

你可能感兴趣的:(spring,cloud)