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