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:
<!-- 指定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/