读者应具备:
- 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相关依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
- 创建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之后呢? <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
- yup. 你没看错,就只有这么几行。这个以
spring-boot-starter
开头的依赖称作起步依赖
。可以把它看成是Spring Boot应用程序必须要导入的依赖。它里面封装了很多的其他的依赖。这里,我们需要开发Spring应用程序,只需要导入一个spring-boot-starter
即可。 - 编写DAO接口和实现 public interface UserDao {
1. /**
* 根据ID获取用户
* @param id
* @return
*/
User get(int id);
} 为了简单,这里就先不从数据中查询数据,直接构建一些User对象来操作(User实体类之前已经给出) @Repository
public class UserDaoImpl implements UserDao{
private ArrayList<User> userList = new ArrayList<User>();
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;
}
}
- 编写服务接口和实现类 public interface UserService {
1. /**
* 根据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);
}
}
- 编写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的测试用例,还需要额外引入另一个起步依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
编写测试用例如下:
@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操作数据库。
导入起步依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
因为,这里需要使用到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起步依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
注意:使用Spring Boot开发JSP应用程序,一定要加载下面的依赖
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
- 编写DAO
1. 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);
}
}
2. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public User get(int id) {
return userDao.get(id);
}
}
3. 编写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<User> users = userService.findAll();
req.setAttribute("list", users);
req.getRequestDispatcher("/index.jsp").forward(req, resp);
}
}
urlPatterns
配置了这个Servlet被访问的URL- 编写JSP页面
1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP测试</title>
</head>
<body>
<table border=1>
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
</tr>
<c:forEach items="${list}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
- 编写入口 @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是不会被加载的。 - 编写配置文件
1. 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)
- 导入依赖
1. <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
</dependency>
</dependencies>
2. 使用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 + "]";
}
}
- 编写DAO
1. public interface UserDao {
User get(int id);
List<User> findAll();
void add(User user);
}
@Repository
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
// 注入SessionFactory
@Autowired
public void autoWiredFactory(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
@Override
public User get(int id) {
return getHibernateTemplate().get(User.class, id);
}
@Override
public List<User> findAll() {
return getHibernateTemplate().findByExample(new User());
}
@Override
public void add(User user) {
getHibernateTemplate().save(user);
}
}
- 编写Service
1. public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public User get(int id) {
return userDao.get(id);
}
@Override
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void add(User user) {
userDao.add(user);
}
}
- 编写Controller/Handler @Controller
1. @RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
}
- JSP页面参见Servlet/JSP案例
- 编写Spring Boot入口
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
return new ComboPooledDataSource();
}
@Bean
@ConfigurationProperties(prefix="hibernate")
public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(c3p0DataSource());
return sessionFactoryBean;
}
@Bean
public HibernateTransactionManager transactionManager() throws PropertyVetoException {
HibernateTransactionManager tx = new HibernateTransactionManager();
tx.setSessionFactory(sessionFactory().getObject());
return tx;
}
}
- 注意:此处因为Hibernate没有Starter起步依赖,所以我使用了Java配置来整合Hibernate。第一个Bean是C3P0数据源,第二个Bean是SessionFactory,第三个Bean是事务管理器。
- 编写配置文件
5. server.port=10086
server.context-path=/
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
hibernate.packagesToScan=com.itheima.springboot.entity
构建SSM应用(Spring、Spring MVC、MyBatis)
为了简单起见,这里使用逆向工程生成实体类、Mapper接口、Mapper映射文件。因为查询实体、映射文件的代码比较长,这里就不把代码贴上来了,大家自己使用逆向工程生成下就OK。
- 导入依赖
1. <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
- Service代码
1. public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
TUser get(int id);
/**
* 查询所有用户
* @return
*/
List<TUser> findAll();
/**
* 新增用户
* @param user
*/
void add(TUser user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private TUserMapper userMapper;
@Override
public TUser get(int id) {
return userMapper.selectByPrimaryKey(id);
}
@Override
public List<TUser> findAll() {
return userMapper.selectByExample(null);
}
@Override
public void add(TUser user) {
userMapper.insert(user);
}
}
- Controller代码
1. @Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<TUser> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
}
- Spring Boot入口应用
1. @SpringBootApplication
@MapperScan(basePackages="com.itheima.springboot.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
} 注意:Spring Boot整合MyBatis需要在Application类上添加@MapperScan,否则不会为Mapper创建代理对象,执行程序失败。
- 配置文件
1. server.port=10086
server.context-path=/
#数据库配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///springboot
spring.datasource.username=root
spring.datasource.password=000000 这里使用默认的数据源,如果想要使用其他的数据源参照之前的配置即可
- 访问http://localhost:10086/user/findUserList
构建SSJPA应用(Spring、Spring MVC、Spring Data JPA)
1. 导入Maven依赖 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies> 注意:导入了spring-boot-starter-data-jpa依赖
2. 编写Java实体类,参考SSH整合JPA实体类
3. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
} (这个代码是真的喜欢)
4. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
5. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
}
6. 编写入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
return new ComboPooledDataSource();
}
}
7. 配置文件 server.port=10086
server.context-path=/
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
构建FreeMarker应用程序
- 导入依赖
1. <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
</dependencies> 多导入了spring-boot-starter-freemarker起步依赖
2. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
}
3. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public User get(int id) {
return userRepository.findOne(id);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public void add(User user) {
userRepository.save(user);
}
}
4. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
// 静态页面输出到的目录
@Value("${freemarker.output_path}")
private String OUTPUT_PATH;
@Autowired
private UserService userService;
// 获取FreeMarker配置类
@Autowired
private Configuration configuration;
@RequestMapping("/genPage")
@ResponseBody
public Map genPage() throws Exception {
List<User> list = userService.findAll();
Map model = new HashMap<String, Object>();
model.put("list", list);
Template template = configuration.getTemplate("user_list.ftl");
template.process(model, new FileWriter(OUTPUT_PATH + "userList.html"));
Map result = new HashMap<String, Object>();
result.put("success", true);
result.put("message", "生成页面成功!");
return result;
}
}
5. 编写入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
return new ComboPooledDataSource();
}
}
6. 编写配置文件 server.port=10086
server.context-path=/
# FreeMarker静态页面输出目录
freemarker.output_path=G:/workspace/free_test/t49/src/main/webapp/
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
7. 编写FreeMarker模板,此模板默认放在classpath下的template/user_list.ftl中 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP测试</title>
</head>
<body>
<table border=1>
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
</tr>
<#list list as user>
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</#list>
</table>
</body>
</html>
8. 访问http://localhost:10086/user/genPage,然后检查HTML页面是否生成
构建基于Redis缓存应用程序
1. 导入依赖 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies> 要开发导入Redis起步依赖spring-boot-starter-data-redis
2. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
}
3. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Autowired
private RedisTemplate redisTemplate;
@Override
public User get(int id) {
return userRepository.findOne(id);
}
@Override
public List<User> findAll() {
Long size = redisTemplate.boundListOps("userList").size();
List<User> userList = redisTemplate.boundListOps("userList").range(0, size);
if(userList == null || size == 0) {
System.out.println("从数据库中获取数据...");
userList = userRepository.findAll();
System.out.println("将数据放入缓存...");
redisTemplate.boundListOps("userList").rightPushAll(userList.toArray(new User[0]));
return userList;
}
else {
System.out.println("从缓存中获取数据...");
return userList;
}
}
@Override
public void add(User user) {
userRepository.save(user);
}
}
4. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
@Value("${freemarker.output_path}")
private String OUTPUT_PATH;
@Autowired
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
}
5. 编写Spring Boot入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
return comboPooledDataSource;
}
}
6. 编写配置文件 server.port=10086
server.context-path=/
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
7. 启动Redis
8. 访问http://localhost:10086/user/findUserList,注意控制台的变化
构建基于ActiveMQ消息队列应用程序
1. 导入依赖 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
</dependencies> 这里导入了ActiveMQ的起步依赖
2. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
}
3. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public User get(int id) {
return userRepository.findOne(id);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public void add(User user) {
userRepository.save(user);
}
}
4. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private JmsTemplate jmsTemplate;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
@RequestMapping("/add")
public String add(User user) {
userService.add(user);
final List<User> userList = userService.findAll();
jmsTemplate.send("queue_page", new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(JSON.toJSONString(userList));
}
});
return "redirect:/user/findUserList";
}
} 在添加一个用户,往AMQ中发送一条queue消息
5. 编写Listener @Component
public class PageGeneratorListener {
@Value("${freemarker.output_path}")
private String OUTPUT_PATH;
@Autowired
private Configuration configuration;
@JmsListener(destination="queue_page")
public void genHtml(String userListStr) throws Exception {
Template template = configuration.getTemplate("user_list.ftl");
List<User> userList = JSON.parseArray(userListStr, User.class);
Map map = new HashMap<String, Object>();
map.put("list", userList);
template.process(map, new FileWriter(OUTPUT_PATH + "user_list.html"));
}
} 监听AMQ中queue_page队列的消息,如果接收到消息,使用FreeMarker重新生成一个HTML页面在服务器端
6. 编写入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
return comboPooledDataSource;
}
}
7. 编写配置文件server.port=10086
server.context-path=/
freemarker.output_path=G:/workspace/free_test/t51/src/main/webapp/
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000构建基于Spring Security访问控制应用程序
1. 导入依赖 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies> 导入了Spring Security的起步依赖spring-boot-starter-security
2. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
// 根据用户名查询用户
User findByUsername(String username);
}
3. 编写Service public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public User get(int id) {
return userRepository.findOne(id);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public void add(User user) {
userRepository.save(user);
}
}
4. 编写Spring Security登录验证用户服务 @Service
@Transactional
public class AuthUserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(StringUtils.isNotBlank(username)) {
// 从数据库中获取用户
User user = userRepository.findByUsername(username);
if(user != null) {
// 创建用户、加载角色
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new org.springframework.security.core.userdetails.User(
username, user.getPassword(), authorities);
}
else {
throw new UsernameNotFoundException("用户名不存在");
}
}
return null;
}
}
5. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
@RequestMapping("/add")
public String add(User user) {
userService.add(user);
return "redirect:/user/findUserList";
}
}
6. 编写应用入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
return comboPooledDataSource;
}
}
7. 编写配置文件 server.port=10086
server.context-path=/
freemarker.output_path=G:/workspace/free_test/t51/src/main/webapp/
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
8. 编写页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP测试</title>
</head>
<body>
<table border="1">
<form action="<%=request.getContextPath()%>/user/add" method="post">
<tr>
<td>用户名:<input type="text" name="username"/></td>
<td>密码:<input type="text" name="password"/></td>
<td><input type="submit" value="新增"/></td>
</tr>
</form>
</table>
<table border=1>
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
</tr>
<c:forEach items="${list}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
9. 访问http://localhost:10086/user/findUserList,弹出登录对话框,输入数据库中任意的用户名和密码登录即可。
构建基于Dubbox分布式架构应用程序
启动ZooKeeper
编写服务提供者
1. 导入依赖 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.cjoop</groupId>
<artifactId>spring-boot-starter-dubbox</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies> 这里导入了Dubbox的起步依赖,这样配置起来很方便。
2. 导入实体类,注意因为要在网络上传输,所以要实现Serializable接口 @Entity
@Table(name="t_user")
public class User implements Serializable{
@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 + "]";
}
}
3. 编写DAO public interface UserRepository extends JpaRepository<User, Integer>{
User findByUsername(String username);
}
- 编写Service(注意:请使用Dubbox中的@Service,否则服务将不会被发布) public interface
1. UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public User get(int id) {
return userRepository.findOne(id);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public void add(User user) {
userRepository.save(user);
}
}
- 编写入口
1. @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean(name="datasource")
@Primary
@ConfigurationProperties(prefix="c3p0")
public ComboPooledDataSource c3p0DataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
return comboPooledDataSource;
}
}
- 编写配置文件
1. server.port=10086
server.context-path=/
#配置Dubbo包扫描,自动将带有Service注解的类发布为Dubbox服务
dubbo.annotation.package=com.itheima.springboot.service
dubbo.application.name=com.itheima.user.service
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///springboot
c3p0.user=root
c3p0.password=000000
- 启动应用,如果服务发布成功,可以在Dubbo Admin上看到已经发布的服务
编写服务消费者
- 导入依赖
1. <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.14.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>com.cjoop</groupId>
<artifactId>spring-boot-starter-dubbox</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
</dependencies>
- 引入实体类
1. public class User {
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 + "]";
}
}
2. 引入Service接口 public interface UserService {
/**
* 根据ID获取用户
* @param i
* @return
*/
User get(int id);
/**
* 查询所有用户
* @return
*/
List<User> findAll();
/**
* 新增用户
* @param user
*/
void add(User user);
}
3. 编写Controller @Controller
@RequestMapping("/user")
public class UserController {
@Reference
private UserService userService;
@RequestMapping("/findUserList")
public String findUserList(Model model) {
List<User> list = userService.findAll();
model.addAttribute("list", list);
return "/index.jsp";
}
@RequestMapping("/add")
public String add(User user) {
userService.add(user);
return "redirect:/user/findUserList";
}
}
4. 编写入口 @SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
5. 编写配置文件 server.port=10087
server.context-path=/
dubbo.annotation.package=com.itheima.springboot.controller
dubbo.application.name=com.itheima.user.web
6. 编写页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP测试</title>
</head>
<body>
<table border="1">
<form action="<%=request.getContextPath()%>/user/add" method="post">
<tr>
<td>用户名:<input type="text" name="username"/></td>
<td>密码:<input type="text" name="password"/></td>
<td><input type="submit" value="新增"/></td>
</tr>
</form>
</table>
<table border=1>
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
</tr>
<c:forEach items="${list}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
- 访问http://localhost:10087/user/findUserList
Spring Boot自动配置原理结构分析
通过实践,可以隐约感觉到。Spring Boot相当于基于Maven和Spring做了一个开发平台,使用这个平台可以减少配置、快速开发。那么Spring Boot到底是如何做到的呢?
回想,我们开发的第一个案例。我们只是往pom.xml中进行简单配置,就可以开始进行Spring开发了。
然后,更新项目可以看到,在Maven的依赖中,导入了很多的JAR包。
这两段配置怎么这么神奇,它到底做了什么?先来看看这个spring-boot-starter-parent的pom文件。
先是定义了很多的常量
里面还定义了一些依赖的版本锁定、插件的版本锁定。但没有导入具体的JAR包。
这个spring-boot-starter-parent从spring-boot-dependencies中继承,这个pom文件中定义了大量的版本号、以及版本锁定。
这些版本应该都是做过兼容性测试的,一般不要去修改否则出现不兼容问题是比较麻烦的。
再看看spring-boot-starter这个依赖
这个starter起步依赖中包含了导入了spring-boot依赖,spring-boot依赖导入了spring framework的核心依赖。
spring-boot-autoconfigure依赖,spring-boot-starter-logging会自动日志相关的依赖。
这个spring-boot-autoconfigure里面包含了很多玄机。
我猜想,Spring Boot是通过自动配置,来帮助我们自动创建了很多bean在IOC容器中。
所以接下来要回答两个问题:
1、Spring创建了哪些Bean?
2、因为我们之前都是通过编写很多的配置文件来创建和配置bean的,那Spring是如何读取配置来创建这些bean的?
接着猜:
以前的配置信息肯定还有,Spring不应该是把之前假设的平台全部推倒,而是把常用的配置整合起来了,就省去了我们自己来手动配置的过程。那么,我猜:每一个Starter都会有其对应的配置信息。我们来找一找spring-boot-starter的配置信息。
这个autoconfigure里面有大量的包,而且命名方式是以技术组件来命名的
要知道Spring Boot创建了哪些bean,直接去看自动配置包中,以Configuration结尾的类就可以了。要想看看具体application.properties中应该配置哪些属性,直接去看以properties文件结尾的类就可以了。
来看一段自动配置的源代码,下面这段代码是从JmsAutoConfiguration中截取出来的。
@Configuration
@ConditionalOnClass({ Message.class, JmsTemplate.class })
@ConditionalOnBean(ConnectionFactory.class)
@EnableConfigurationProperties(JmsProperties.class)
@Import(JmsAnnotationDrivenConfiguration.class)
public class JmsAutoConfiguration {
@Configuration
protected static class JmsTemplateConfiguration {
private final JmsProperties properties;
private final ObjectProvider<DestinationResolver> destinationResolver;
private final ObjectProvider<MessageConverter> messageConverter;
public JmsTemplateConfiguration(JmsProperties properties,
ObjectProvider<DestinationResolver> destinationResolver,
ObjectProvider<MessageConverter> messageConverter) {
this.properties = properties;
this.destinationResolver = destinationResolver;
this.messageConverter = messageConverter;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(ConnectionFactory.class)
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setPubSubDomain(this.properties.isPubSubDomain());
DestinationResolver destinationResolver = this.destinationResolver
.getIfUnique();
if (destinationResolver != null) {
jmsTemplate.setDestinationResolver(destinationResolver);
}
MessageConverter messageConverter = this.messageConverter.getIfUnique();
if (messageConverter != null) {
jmsTemplate.setMessageConverter(messageConverter);
}
JmsProperties.Template template = this.properties.getTemplate();
if (template.getDefaultDestination() != null) {
jmsTemplate.setDefaultDestinationName(template.getDefaultDestination());
}
if (template.getDeliveryDelay() != null) {
jmsTemplate.setDeliveryDelay(template.getDeliveryDelay());
}
jmsTemplate.setExplicitQosEnabled(template.determineQosEnabled());
if (template.getDeliveryMode() != null) {
jmsTemplate.setDeliveryMode(template.getDeliveryMode().getValue());
}
if (template.getPriority() != null) {
jmsTemplate.setPriority(template.getPriority());
}
if (template.getTimeToLive() != null) {
jmsTemplate.setTimeToLive(template.getTimeToLive());
}
if (template.getReceiveTimeout() != null) {
jmsTemplate.setReceiveTimeout(template.getReceiveTimeout());
}
return jmsTemplate;
}
}
这里面有几个很重要的注解
- @ConditionalOnClass
这个注解表示,如果检测到当前的JVM中加载了Message.class, JmsTemplate.class,就加载该Java Config配置。 - @ConditionalOnMissingBean
这个注解表示,如果IOC容器中没有检测到这个类型的Bean,就创建一个。如果检测到了,那么就不创建了。所以,如果我们自己配置了JmsTemplate这个Bean,那这个自动配置就失效了 - @ConditionalOnBean
这个注解表示,如果IOC容器中有指定类型的Bean,才加载Java Config配置。例如:这里如果检测到容器中有ConnectionFactory类型的Bean,才会创建JmsTemplate。 - @EnableConfigurationProperties
这个注解表示将以Properties结尾的配置类,加载到当前的自动配置类中。一般的Starter中的Properties类都可以从application.properties中的指定前缀的属性加载。从而让我们可以轻松的自定义里面的配置。 - @Import
导入其他的Java Config配置,相当于之前XML配置中的import。
结尾
大家应该有一个直接的体会,Spring Boot真的让我们的工作更加轻松了。以前要写的很多配置、导很多的依赖,现在只需要短短几行代码就可以解决问题。而且,不再需要我们去考虑版本之间的兼容问题了。相信,很快大家编写的应用都会切换到Spring Boot。它将让我们将更多的精力放在编写、设计结构、算法上。
标签:场景,return,Spring,boot,id,user,Boot,public From: https://blog.51cto.com/u_16147814/7031144