spring boot自动化配置原理

来源:互联网 发布:php addcslashes 编辑:程序博客网 时间:2024/05/17 12:19

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;@Configurationpublic 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;@Servicepublic class MyBookService implements IBookService{}

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

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

spring boot的自动注解做了什么

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

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

    <!-- 指定bean 容器上下文配置文件 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:spring/**/*.xml,classpath:*.xml</param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <!-- 编码过滤器 -->    <filter>        <filter-name>encodingFilter</filter-name>        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>        <async-supported>true</async-supported>        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>encodingFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- Spring MVC 前端控制器 -->    <servlet>        <servlet-name>SpringMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:spring/appconfig/spring-mvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>        <async-supported>true</async-supported>    </servlet>    <servlet-mapping>        <servlet-name>SpringMVC</servlet-name>        <url-pattern>/*</url-pattern>    </servlet-mapping>  

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

    <!-- 定义跳转的文件的前后缀 ,视图模式配置 -->    <bean   class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->        <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.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>javax.servlet</groupId>            <artifactId>jstl</artifactId>        </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.boot</groupId>            <artifactId>spring-boot-starter</artifactId>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-context-support</artifactId>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-tx</artifactId>        </dependency>        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz</artifactId>        </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/

原创粉丝点击