1.改造購物車系統
1.1.建立購物車的Spring Boot工程
1.1.導入依賴 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <groupId>com.taotao.cart</groupId> <artifactId>taotao-cart-springboot</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.taotao.common</groupId> <artifactId>taotao-common</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.taotao.sso</groupId> <artifactId>taotao-sso-interface</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <!-- 單元測試 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- 分頁助手 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>3.7.5</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>0.9.1</version> </dependency> <!-- 通用Mapper --> <dependency> <groupId>com.github.abel533</groupId> <artifactId>mapper</artifactId> <version>2.3.4</version> </dependency> <!-- MySql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <!-- 鏈接池 --> <dependency> <groupId>com.jolbox</groupId> <artifactId>bonecp-spring</artifactId> <version>0.8.0.RELEASE</version> </dependency> <!-- httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <!-- JSP相關 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Apache工具組件 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>1.4.0.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <!-- 排除傳遞spring依賴 --> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.3.3</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> <build> <plugins> <!-- 資源文件拷貝插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- java編譯插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 1.2.將taotao-cart中的java代碼拷貝到taotao-car-springboot
拷貝完成後:java
而且將properties文件也拷貝過來:node
將頁面也拷貝過來:web.xml在spring-boot中是不須要的。mysql
1.1.1.設置tomcat端口
application.properties:
讀取外部的配置文件
@Configuration
@PropertySource(value = { "classpath:jdbc.properties", "classpath:env.properties",
"classpath:httpclient.properties", "classpath:redis.properties", "classpath:rabbitmq.properties" }, ignoreResourceNotFound = true)
public class TaotaoApplication {
}
1.1.1.設置掃描包
1.1.1.定義數據源 @Value("${jdbc.url}") private String jdbcUrl; @Value("${jdbc.driverClassName}") private String jdbcDriverClassName; @Value("${jdbc.username}") private String jdbcUsername; @Value("${jdbc.password}") private String jdbcPassword; @Bean(destroyMethod = "close") public DataSource dataSource() { BoneCPDataSource boneCPDataSource = new BoneCPDataSource(); // 數據庫驅動 boneCPDataSource.setDriverClass(jdbcDriverClassName); // 相應驅動的jdbcUrl boneCPDataSource.setJdbcUrl(jdbcUrl); // 數據庫的用戶名 boneCPDataSource.setUsername(jdbcUsername); // 數據庫的密碼 boneCPDataSource.setPassword(jdbcUsername); // 檢查數據庫鏈接池中空閒鏈接的間隔時間,單位是分,默認值:240,若是要取消則設置爲0 boneCPDataSource.setIdleConnectionTestPeriodInMinutes(60); // 鏈接池中未使用的連接最大存活時間,單位是分,默認值:60,若是要永遠存活設置爲0 boneCPDataSource.setIdleMaxAgeInMinutes(30); // 每一個分區最大的鏈接數 boneCPDataSource.setMaxConnectionsPerPartition(100); // 每一個分區最小的鏈接數 boneCPDataSource.setMinConnectionsPerPartition(5); return boneCPDataSource; } 1.1.2.設置Mybatis和Spring Boot整合 Spring Boot官方沒有提供Mybatis自動配置的starter,不能直接去用,Mybatis和Spring Boot的整合有兩種方式: 第一種:使用mybatis官方提供的Spring Boot整合包實現,地址:https://github.com/mybatis/spring-boot-starter 第二種:使用mybatis-spring整合的方式,也就是咱們傳統的方式,xml的方式改爲java方式。 這裏咱們推薦使用第二種,由於這樣咱們能夠很方便的控制Mybatis的各類配置,便於擴展mybatis。 首先,建立一個Mybatis的配置類:
代碼: import javax.sql.DataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; @Configuration public class MyBatisConfig { @Bean @ConditionalOnMissingBean //當容器裏沒有指定的Bean的狀況下建立該對象 public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); // 設置數據源 sqlSessionFactoryBean.setDataSource(dataSource); // 設置mybatis的主配置文件 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource mybatisConfigXml = resolver.getResource("classpath:mybatis/mybatis-config.xml"); sqlSessionFactoryBean.setConfigLocation(mybatisConfigXml); // 設置別名包 sqlSessionFactoryBean.setTypeAliasesPackage("com.taotao.cart.pojo"); return sqlSessionFactoryBean; } } 而後,建立Mapper接口的掃描類MapperScannerConfig:如圖上面的xml文件中的bean
代碼: import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @AutoConfigureAfter(MyBatisConfig.class) //保證在MyBatisConfig實例化以後再實例化該類 public class MapperScannerConfig { // mapper接口的掃描器 @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setBasePackage("com.taotao.cart.mapper"); return mapperScannerConfigurer; } } 1.1.1.設置事務管理 在Spring Boot中推薦使用@Transactional註解來申明事務。
首先須要導入依賴: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 當引入jdbc依賴以後,Spring Boot會作一系列的初始化操做,而且把一些初始化的事務管理都搞定了,並把事務Spring Boot會自動默認分別注入DataSourceTransactionManager或JpaTransactionManager,不須要咱們配置DataSourceTransactionManager類了。因此咱們不須要任何額外配置就能夠用@Transactional註解進行事務的使用。 在Service中添加@Transactional註解:CartService類是和數據庫有關係的,因此要加事務。加到類上是全部的public方法都有事務。
1.1.1.設置Redis和Spring的整合 在Spring Boot中提供了RedisTempplate的操做,咱們暫時不作學習,先按照咱們以前的實現來完成。 代碼: import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedisPool; @Configuration @PropertySource(value = "classpath:redis.properties") public class RedisSpringConfig { @Value("${redis.maxTotal}") private Integer redisMaxTotal; @Value("${redis.node1.host}") private String redisNode1Host; @Value("${redis.node1.port}") private Integer redisNode1Port; private JedisPoolConfig jedisPoolConfig() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(redisMaxTotal); return jedisPoolConfig; } @Bean public ShardedJedisPool shardedJedisPool() { List<JedisShardInfo> jedisShardInfos = new ArrayList<JedisShardInfo>(); jedisShardInfos.add(new JedisShardInfo(redisNode1Host, redisNode1Port)); return new ShardedJedisPool(jedisPoolConfig(), jedisShardInfos); } } 1.1.2.設置Httpclient和Spring的整合
import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import com.taotao.common.httpclient.IdleConnectionEvictor; @Configuration @PropertySource(value = "classpath:httpclient.properties") public class HttpclientSpringConfig { @Value("${http.maxTotal}") private Integer httpMaxTotal; @Value("${http.defaultMaxPerRoute}") private Integer httpDefaultMaxPerRoute; @Value("${http.connectTimeout}") private Integer httpConnectTimeout; @Value("${http.connectionRequestTimeout}") private Integer httpConnectionRequestTimeout; @Value("${http.socketTimeout}") private Integer httpSocketTimeout; @Value("${http.staleConnectionCheckEnabled}") private Boolean httpStaleConnectionCheckEnabled; @Autowired private PoolingHttpClientConnectionManager manager; @Bean public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() { PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(); // 最大鏈接數 poolingHttpClientConnectionManager.setMaxTotal(httpMaxTotal); // 每一個主機的最大併發數 poolingHttpClientConnectionManager.setDefaultMaxPerRoute(httpDefaultMaxPerRoute); return poolingHttpClientConnectionManager; } // 按期關閉無效鏈接 @Bean public IdleConnectionEvictor idleConnectionEvictor() { return new IdleConnectionEvictor(manager); } // 定義Httpclient對 @Bean @Scope("prototype") public CloseableHttpClient closeableHttpClient() { return HttpClients.custom().setConnectionManager(this.manager).build(); } // 請求配置 @Bean public RequestConfig requestConfig() { return RequestConfig.custom().setConnectTimeout(httpConnectTimeout) // 建立鏈接的最長時間 .setConnectionRequestTimeout(httpConnectionRequestTimeout) // 從鏈接池中獲取到鏈接的最長時間 .setSocketTimeout(httpSocketTimeout) // 數據傳輸的最長時間 .setStaleConnectionCheckEnabled(httpStaleConnectionCheckEnabled) // 提交請求前測試鏈接是否可用 .build(); } } 1.1.1.設置RabbitMQ和Spring的整合 咱們以前使用的Spring-Rabbit的xml方式,如今咱們要改形成java方式,而且Spring Boot對RabbitMQ的使用作了自動配置,更加的簡化了咱們的使用。 在導入spring-boot-starter-amqp的依賴;
在application.properties文件中配置RabbitMQ的鏈接信息git
3、編寫Rabbit的Spring配置類 import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //以前都是寫在xml配置文件 public class RabbitMQSpringConfig { @Autowired //鏈接工廠是springboot幫咱們構建的,不須要配置,這裏直接使用。 private ConnectionFactory connectionFactory; // 管理 @Bean public RabbitAdmin rabbitAdmin() { return new RabbitAdmin(connectionFactory); } // 聲明隊列 @Bean public Queue taotaoCartLoginQueue() { // 默認就是自動聲明的 return new Queue("TAOTAO-CART-LOGIN-QUEUE", true); } // 聲明隊列 @Bean public Queue taotaoCartOrderSuccessQueue() { // 默認就是自動聲明的 return new Queue("TAOTAO-CART-ORDER-SUCCESS-QUEUE", true); } } 設置監聽:以前都是寫在xml配置文件裏面的。
1.1.1.設置SpringMVC的配置
原有配置:springboot也會自動掃描,因此這個不須要了。註解驅動就是springmvc的自動配置升級版,springboot對springmvc也作了自動配置。視圖解析器是前綴後綴。配置攔截器繼承WebMvcConfigurerAdapter 重寫addInterceptors方法。
具體實現:
視圖解析器配置:
自定義攔截器: import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.taotao.cart.interceptors.UserLoginHandlerInterceptor; @Configuration public class SpringMVCConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { // 判斷用戶是否登陸的攔截器 registry.addInterceptor(new UserLoginHandlerInterceptor()).addPathPatterns("/cart/**"); } } 1.1.1.設置dubbo的配置 Dubbo目前只能使用xml配置的方式,因此咱們須要保留xml,而且須要將該xml加入到現有的Spring容器中才能生效。 將dubbo目錄以及下面的xml配置文件拷貝到taotao-cat-springboot中
將dubbo的xml文件加入到spring容器github
1.1.1.啓動錯誤1
關鍵錯誤(丟失了web容器的工廠,也就是說咱們並無把它做爲一個web應用來啓動):
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
解決:
讓Spring Boot來自動選擇而且完成web的相關加載工做。web
提示咱們當前的項目中slf4j引入了2個,致使了jar衝突。
解決:
刪除本身引入到slf4j的依賴,保留springboot的依賴。
將taotao-common中傳遞的依賴排除掉redis
1.1.1.解決jsp訪問404的問題
因爲Spring boot使用的內嵌的tomcat,而內嵌的tamcat是不支持jsp頁面的,全部須要導入額外的包才能解決。Springboot不支持jsp而推薦模版引擎。
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
1.1.1.攔截器中的UserService空指針異常
分析:因爲添加攔截器時,直接對UserLoginHandlerInterceptor進行new操做,致使UserService沒法注入,因此有空指針異常。
解決:
1.發佈到獨立的tomcat中運行
在開發階段咱們推薦使用內嵌的tomcat進行開發,由於這樣會方便不少,可是到生成環境,我但願在獨立的tomcat容器中運行,由於咱們須要對tomcat作額外的優化,這時咱們須要將工程打包成war包發進行發佈。
1.1.工程的打包方式爲war
1.1.將spring-boot-starter-tomcat的範圍設置爲provided 設置爲provided是在打包時會將該包排除,由於要放到獨立的tomcat中運行,是不須要spring-boot-starter-tomcat的。spring-boot-starter-web也是會傳遞加載tomcat的。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> 1.2.修改代碼,設置啓動配置 須要集成SpringBootServletInitializer,而後重寫configure,將Spring Boot的入口類設置進去。
打包成功:spring
解壓apache-tomcat-7.0.57.tar.gz,將war包解壓到webapps下的ROOT目錄中,啓動:沒有web.xml文件,springboot幫助咱們搞了。sql