读者应具备:
- Spring SpringMVC服务器端开发基础
- Maven基础
本篇主要介绍Spring Boot在企业开发中常见场景的使用、以及Spring Boot的基本原理结构。
以下为本篇设计的技术应用场景:
- 构建Spring Java程序
- 构建JUnit测试用例
- 构建Spring JDBC Template应用程序操作数据库
- 构建Servlet、JSP程序
- 构建SSH应用(Spring、Spring MVC、Hibernate)
- 构建SSM应用(Spring、Spring MVC、MyBatis)
- 构建SSJPA应用(Spring、Spring MVC、Spring Data JPA)
- 构建FreeMarker应用程序
- 构建基于Redis缓存应用程序
- 构建基于ActiveMQ消息队列应用程序
- 构建基于Spring Security访问控制应用程序
- 构建基于Dubbox分布式架构应用程序
介绍完应用场景后,再来了解下Spring Boot的基本原理结构。
引言
如果读者写过稍微复杂一些的Spring程序,那么你一定曾经编写过那铺天盖地的各类配置文件。例如:
- applicationContext-dao.xml(针对DAO的配置——数据源、持久层框架与spring整合bean)
- applicationContext-tx.xml(针对事务的配置)
- applicationContext-amq.xml(针对ActiveMQ的配置)
- applicationContext-webservice.xml(针对WebService发布的配置)
- applicationContext-redis.xml(针对操作Redis的配置)
- applicationContext-security.xml(针对Spring Security的配置)
- applicationContext-freemarker.xml(针对FreeMarker模板引擎的相关配置)
- springmvc.xml(Spring MVC的配置)
- ...
除此之外,我们还要维护大量的依赖。最坑的是,不同的版本框架之间可能会存在不兼容的问题。或许,我们早已习惯了这些配置,但我们今天要学习是以一种崭新的开发方式来开发Spring应用程序。它将掀起一场推翻Spring过去统治的轻量级JavaEE企业应用世界的技术革命。
而这一场技术革命原动力就是我今天要呈现给大家的——Spring Boot。
本篇目标
- 介绍如何使用Spring Boot开发基于各类技术框架的应用程序
- 了解Spring Boot自动配置原理、结构
目录
Spring Boot常见企业开发场景应用、自动配置原理结构分析引言本篇目标目录环境准备Spring Java配置Spring Boot基本编程模型导入依赖导入配置编码常见企业开发场景应用构建Spring Java应用程序构建Junit测试用例构建Spring JDBC Template应用程序操作数据库构建Servlet、JSP程序构建SSH应用程序(Spring、Spring MVC、Hibernate)构建SSM应用(Spring、Spring MVC、MyBatis)构建SSJPA应用(Spring、Spring MVC、Spring Data JPA)构建FreeMarker应用程序构建基于Redis缓存应用程序构建基于ActiveMQ消息队列应用程序构建基于Dubbox分布式架构应用程序启动ZooKeeper编写服务提供者编写服务消费者Spring Boot自动配置原理结构分析结尾
环境准备
编译环境:1.7+
构建工具:Maven
数据库:Mysql 5.x
开发环境:推荐使用IDEA或者STS
- 在mysql中创建一个名字为springboot的数据库
- 使用如下脚本创建表结构
create table `t_user` ( `id` int (11), `username` varchar (765), `password` varchar (300) ); insert into `t_user` (`id`, `username`, `password`) values('2','zhangsan','000'); insert into `t_user` (`id`, `username`, `password`) values('3','lisi','000'); insert into `t_user` (`id`, `username`, `password`) values('4','wangwu','000'); insert into `t_user` (`id`, `username`, `password`) values('5','zhaoliu','000'); insert into `t_user` (`id`, `username`, `password`) values('6','张北','110'); insert into `t_user` (`id`, `username`, `password`) values('7','江南','000000'); insert into `t_user` (`id`, `username`, `password`) values('8','江北','123123');
Spring Java配置
SPring Java配置是Spring 3.0所推荐的配置方式。因为,XML的可读性确实不怎么样,我们一边要编写Java代码,一边要编写XML配置文件。所以,从Spring 3.0开始,推荐使用Java配置+注解方式来编写Spring程序。
接下来,我给大家演示一个比较简单的案例——从数据库中更新一条用户数据、查询一条用户数据。为了简单起见,使用Spring JDBC Template来操作数据库。
- 首先创建一个Maven工程,往pom.xml中导入Spring、MySql相关依赖
org.springframework spring-context 4.2.4.RELEASE org.springframework spring-jdbc 4.2.4.RELEASE org.springframework spring-test 4.2.4.RELEASE mysql mysql-connector-java 5.1.6 junit junit 4.12 c3p0 c3p0 0.9.1 org.apache.maven.plugins maven-compiler-plugin 3.1 1.7 1.7
- 创建Java实体类,
/** * 用户表 */ public class User { private Integer id; private String username;// 用户名 private String password;// 密码 public User() { } public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
- 写到这,如果大家比较熟悉Spring开发的话,肯定是要开始编写spring配置文件了,并且在配置文件中,创建需要用于操作数据库的Bean。但这儿,我们要使用Java配置来创建Bean。以前在XML文件中创建Bean的配置,现在都写在Java代码中了。以下为Java配置:
/** * @Configuration注解表示这是一个配置类 * @author FengZhou * */ @Configuration public class Conf { /** * 创建一个C3P0数据源 * @return * @throws PropertyVetoException */ @Bean public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver"); comboPooledDataSource.setJdbcUrl("jdbc:mysql:///springboot"); comboPooledDataSource.setUser("root"); comboPooledDataSource.setPassword("000000"); return comboPooledDataSource; } /** * 创建一个用于操作数据库的JdbcTemplate * @return * @throws PropertyVetoException */ @Bean public JdbcTemplate jdbcTempalte() throws PropertyVetoException { JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(c3p0DataSource()); return jdbcTemplate; } }
@Configuration
这个注解标识,当前修饰的类就是一个配置类。你可以把它认为被@Configuration修饰的类就是一个配置文件。
@Bean
这个注解表示Spring会自动执行被它修饰的方法,并且将此方法的返回对象放入到Spring IOC容器中。
上述代码创建了两个Bean,分别是C3P0的数据源和用于操作数据的JdbcTemplate。
- 编写测试用例
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=Conf.class)// 加载Java配置 public class JdbcTemplateTest01 { @Autowired private JdbcTemplate jdbcTemplate; @Test public void test01() { // 执行一条更新语句 jdbcTemplate.execute("update t_user t set t.username='zhaosi' where t.id = 1"); } @Test public void test02() { // 查询一条数据 jdbcTemplate.query("select * from t_user where id = 2", BeanPropertyRowMapper.newInstance(User.class)); } }
本次的测试用例,不再有applicationContext.xml配置文件,而是使用一个Java配置类代替了这个配置文件。
Spring Boot基本编程模型
接下来,我们要开始使用Spring Boot开发应用程序。Spring Boot的基本开发模型如下:
导入依赖
1、添加起步依赖(这个起步依赖不是具体的JAR包,而是你要开发什么样的功能,就使用什么样的起步依赖)——注意:可以把起步依赖看成一个Spring Boot封装过的特殊依赖,这个依赖也是具备有传递性特征的
2、导入其他关联依赖(数据库驱动、JSTL等)
导入配置
1、配置application.properties或者application.yml
2、编写Java自定义配置
编码
1、编写Main入口,并加载SpringBoot自动配置
2、编写业务代码
a) 获取Spring Boot自动配置生成的BEAN Template
b) 使用BEAN Template来执行业务操作
大家可以先不用了解Spring Boot开发的具体细节,只需要重点记住这几个重点:
- 导入依赖
- 导入配置
- 编写代码
这个过程其实和我们之前的Spring开发并没有太大区别。
常见企业开发场景应用
构建Spring Java应用程序
第一个应用不涉及到数据库的操作。我们的目标是使用Spring Boot来编写一个简单的Java程序。这个Java程序只是通过Spring Boot来创建一个Spring IOC容器,并从调用容器中Bean的方法。
- 导入Spring Boot依赖
还记得前面的代码吗?我们在创建Maven项目后,需要往pom.xml中导入很多的以来。而使用了Spring Boot之后呢?
org.springframework.boot spring-boot-starter-parent 1.5.14.RELEASE org.springframework.boot spring-boot-starter
- yup. 你没看错,就只有这么几行。这个以
spring-boot-starter
开头的依赖称作起步依赖
。可以把它看成是Spring Boot应用程序必须要导入的依赖。它里面封装了很多的其他的依赖。这里,我们需要开发Spring应用程序,只需要导入一个spring-boot-starter
即可。 - 编写DAO接口和实现
public interface UserDao { /** * 根据ID获取用户 * @param id * @return */ User get(int id); } 1. 为了简单,这里就先不从数据中查询数据,直接构建一些User对象来操作(User实体类之前已经给出) @Repository public class UserDaoImpl implements UserDao{ private ArrayList userList = new ArrayList(); public UserDaoImpl() { // 往数组中添加一些模拟测试数据 userList.add(new User(1, "zhangsan", "000")); userList.add(new User(2, "lisi", "000")); userList.add(new User(3, "wangwu", "000")); userList.add(new User(4, "zhaoliu", "000")); } @Override public User get(int id) { for (User user : userList) { if(user.getId().equals(id)) { return user; } } return null; } } 1. 编写服务接口和实现类 public interface UserService { /** * 根据ID获取用户 * @param i * @return */ User get(int id); } @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User get(int id) { return userDao.get(id); } } 1. 编写Spring Boot应用程序入口 @SpringBootApplication public class Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Application.class); UserService userService = context.getBean(UserService.class); User user = userService.get(1); System.out.println(user); } }
- 注意:
要在main所在的Applcation类上添加@SpringBootApplication
注解,这个注解会启动Spring Boot的自动配置。然后使用SpringApplication.run可以创建一个Spring IOC工厂,它的返回值就是我们熟知的ApplicationContext。然后,我们就可以获取IOC工厂的Bean了。
构建Junit测试用例
要构建基于Spring Boot的测试用例,还需要额外引入另一个起步依赖。
org.springframework.boot
spring-boot-starter-test
编写测试用例如下:
@RunWith(SpringRunner.class) @SpringBootTest(classes=Application.class) public class UserServiceImplTest { @Autowired private UserService userService; @Test public void testGet() { User user = userService.get(2); System.out.println(user); } }
使用@SpringBootTest替代之前的@ContextConfiguration,直接加载Spring Boot的入口类即可。
构建Spring JDBC Template应用程序操作数据库
接下来,我将使用Spring Boot来使用JDBC Template操作数据库。
导入起步依赖
org.springframework.boot spring-boot-starter-parent 1.5.14.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java 5.1.6 c3p0 c3p0 0.9.1
因为,这里需要使用到mysql驱动以及c3p0连接池,所以多导入了两个依赖
重新编写DAO
public interface UserDao { /** * 根据ID获取用户 * @param id * @return */ User get(int id); } @Repository public class UserDaoImpl implements UserDao{ @Autowired private JdbcTemplate jdbcTemplate; @Override public User get(int id) { return jdbcTemplate.queryForObject("select * from t_user t where t.id = ?",BeanPropertyRowMapper.newInstance(User.class),id); } } 编写Service public interface UserService { /** * 根据ID获取用户 * @param i * @return */ User get(int id); } @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User get(int id) { return userDao.get(id); } } 编写配置文件application.properties c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql:///springboot c3p0.user=root c3p0.password=000000
注意:这个配置文件中以c3p0开头的,其实是自定义的配置。一会我们需要指定这个前缀来进行加载
编写启动类
@SpringBootApplication public class Application { @Bean(name="datasource") @Primary @ConfigurationProperties(prefix="c3p0") public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException { return new ComboPooledDataSource(); } public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Application.class); UserService userService = context.getBean(UserService.class); User user = userService.get(2); System.out.println(user); } }
注意@ConfigurationProperties(prefix="c3p0")
这个注解,这个注解表示,将application.properties配置文件中的以c3p0开头的配置信息注入到ComboPooledDataSource这个对象上面。而在application.properties中的配置c3p0.driverClass=com.mysql.jdbc.Driver
,相当于就是在进行属性注入。这里指的是:将com.mysql.jdbc.Driver注入到ComboPooledDataSource Bean的driverClass属性。
这种加载配置的方法,真的是不服不行。要比之前简单了很多。
构建Servlet、JSP程序
接下来我们要来使用Spring Boot来做最简单的Web开发(虽然我们开发不一定会用到,但我们还是来体验体验,毕竟这是我们的曾经啊...)
- 导入Spring Boot起步依赖
org.springframework.boot spring-boot-starter-parent 1.5.14.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc org.apache.tomcat.embed tomcat-embed-jasper provided mysql mysql-connector-java 5.1.6 c3p0 c3p0 0.9.1 javax.servlet jstl
注意:使用Spring Boot开发JSP应用程序,一定要加载下面的依赖
org.apache.tomcat.embed tomcat-embed-jasper provided 1. 编写DAO public interface UserDao { /** * 根据ID获取用户 * @param id * @return */ User get(int id); } @Repository public class UserDaoImpl implements UserDao{ @Autowired private JdbcTemplate jdbcTemplate; @Override public User get(int id) { return jdbcTemplate.queryForObject("select * from t_user t where t.id = ?",BeanPropertyRowMapper.newInstance(User.class),id); } } 1. 编写Service public interface UserService { /** * 根据ID获取用户 * @param i * @return */ User get(int id); /** * 查询所有用户 * @return */ List findAll(); } @Service @Transactional public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User get(int id) { return userDao.get(id); } } 1. 编写Servlet | 这里使用的是注解方式定义Servlet,这种方式更加容易与Spring进行整合。 @WebServlet(name="UserServlet", urlPatterns="/user/findUserList") public class UserServlet extends HttpServlet{ @Autowired private UserService userService; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List users = userService.findAll(); req.setAttribute("list", users); req.getRequestDispatcher("/index.jsp").forward(req, resp); } }
urlPatterns
配置了这个Servlet被访问的URL- 编写JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> JSP测试 ID 用户名 密码 ${user.id} ${user.username} ${user.password} 1. 编写入口 @SpringBootApplication @ServletComponentScan public class Application { @Bean(name="datasource") @ConfigurationProperties(prefix="c3p0") public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException { return new ComboPooledDataSource(); } public static void main(String[] args) { SpringApplication.run(Application.class); } }
- 注意:一定要在Application类上加上
@ServletComponentScan
注解,否则Servlet是不会被加载的。 - 编写配置文件
server.port=10086 server.context-path=/ c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql:///springboot c3p0.user=root c3p0.password=000000
server.port
配置的是web应用访问的端口号,server.context-path=/是应用访问的根路径- 访问http://localhost:10086/user/findUserList测试应用。如果应用执行成功应该可以看到用户数据
构建SSH应用程序(Spring、Spring MVC、Hibernate)
- 导入依赖
org.springframework.boot spring-boot-starter-parent 1.5.14.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc org.apache.tomcat.embed tomcat-embed-jasper provided mysql mysql-connector-java 5.1.6 c3p0 c3p0 0.9.1 javax.servlet jstl org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-actuator org.springframework spring-tx org.springframework.boot spring-boot-starter-test javassist javassist 3.11.0.GA 1. 使用JPA注解修饰User实体类 @Entity @Table(name="t_user") public class User { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String username; private String password; public User() { } public User(Integer id, String username, String password) { this.id = id; this.username = username; this.password = password; } public User(String username, String password) { this(null, username, password); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
Spring Boot常见企业开发场景应用、自动配置原理结构分析(二)https://developer.aliyun.com/article/1423060