Spring 框架的常見問題是要快速建立一個能夠運行的應用比較麻煩,對於新接觸 Spring 框架的開發人員來講,並不知道如何更好的使用這些組件。css
Spring Boot 是 Spring 框架的一個新的子項目,用於建立 Spring 4.0 項目。它的開發始於 2013 年。2014 年 4 月發佈 1.0.0 版本。它能夠自動配置 Spring 的各類組件,並不依賴代碼生成和 XML 配置文件。Spring Boot 也提供了對於常見場景的推薦組件配置。Spring Boot 能夠大大提高使用 Spring 框架時的開發效率。html
Ø 使用Spring boot ,能夠輕鬆的建立獨立運行的程序,很是容易構建獨立的服務組件,是實現分佈式架構、微服務架構利器。java
Ø Spring boot簡化了第三方包的引用,經過提供的starter,簡化了依賴包的配置。mysql
Ø 輕鬆建立獨立的Spring應用程序。web
Ø 內嵌Tomcat、jetty等web容器,不須要部署WAR文件。spring
Ø 提供一系列的「starter」 來簡化的Maven配置,不須要添加不少依賴。sql
Ø 開箱即用,儘量自動配置Spring。mongodb
Name | Servlet Version | Java Version |
---|---|---|
Tomcat 8 | 3.1 | Java 7+ |
Tomcat 7 | 3.0 | Java 6+ |
Jetty 9.3 | 3.1 | Java 8+ |
Jetty 9.2 | 3.1 | Java 7+ |
Jetty 8 | 3.0 | Java6+ |
解壓一個maven3.5到本地shell
修改maven的conf\setting的本地倉庫存儲路徑數據庫
修改maven的conf\setting 中遠程倉庫爲阿里雲的
把Eclipse中的本地和全局的倉庫文件都改爲conf\setting
建立一個 maven war項目(test1)或建立一個 maven jar(test2)。 這兩種均可以,但通常都使用jar,由於spring是用於服務,不建議與jsp使用
+springbootdemo1 pom.xml
+springbootdemo2 pom.xml
在pom.xml添加spring-boot-starter-web依賴,如圖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
spring-boot-starter-parent做用:
在pom.xml中引入spring-boot-start-parent,它能夠提供dependency management,也就是說依賴管理,引入之後在申明其它dependency的時候就不須要version了,後面能夠看到。
spring-boot-starter-web做用:springweb 核心組件
寫一個控制器以下,而後寫一個main方法,把程序跑起來:
package com.jihaiyang.web.controller; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController//至關於聲明Controller - 提共restful 風格 @EnableAutoConfiguration//自動配置,不須要寫spring的配置文件 class HelloController { @RequestMapping(value = "hello/{name}") public String hello1(@PathVariable("name") String name){ return name+"Hello,SpringBoot"; } public static void main(String[] args) { SpringApplication.run(HelloController.class);//啓動當前控制器 } }
在瀏覽器中訪問http://localhost:8080/hello
在控制器配置@EnableAutoConfiguration並使用SpringApplication.run()啓動程序
建立一個App類,在App類中配置@EnableAutoConfiguration和組件掃描ComponentScan,
而後使用SpringApplication啓動程序,這樣就能夠訪問多個Controller了.
@RequestMapping("{id}") @ResponseBody public User userInfo(@PathVariable(varlue="id") Integer id) { User user=new User("gyf","123"); return user; }
建立App類
@ComponentScan(basePackages="com.jihaiyang.web.controller")//controller所在的包進行掃描 @EnableAutoConfiguration//此處只需寫一個,其餘控制器不用寫了 public class App{ public static void main(String[] args){ SpringApplication.run(App.class,args); } }
spring-boot-starter | 核心 POM,包含自動配置支持、日誌庫和對 YAML 配置文件的支持 |
---|---|
spring-boot-starter-amqp | 經過 spring-rabbit 支持 AMQP |
spring-boot-starter-aop | 包含 spring-aop 和 AspectJ 來支持面向切面編程(AOP)。 |
spring-boot-starter-batch | 支持 Spring Batch,包含 HSQLDB。 |
spring-boot-starter-data-jpa | 包含 spring-data-jpa、spring-orm 和 Hibernate 來支持 JPA。 |
spring-boot-starter-data-mongodb | 包含 spring-data-mongodb 來支持 MongoDB。 |
spring-boot-starter-data-rest | 經過 spring-data-rest-webmvc 支持以 REST 方式暴露 Spring Data 倉庫。 |
spring-boot-starter-jdbc | 支持使用 JDBC 訪問數據庫 |
spring-boot-starter-security | 包含 spring-security。 |
spring-boot-starter-test | 包含經常使用的測試所需的依賴,如 JUnit、Hamcrest、Mockito 和 spring-test 等。 |
spring-boot-starter-velocity | 支持使用 Velocity 做爲模板引擎。 |
spring-boot-starter-web | 支持 Web 應用開發,包含 Tomcat 和 spring-mvc。 |
spring-boot-starter-websocket | 支持使用 Tomcat 開發 WebSocket 應用。 |
spring-boot-starter-ws | 支持 Spring Web Services |
spring-boot-starter-actuator | 添加適用於生產環境的功能,如性能指標和監測等功能。 |
spring-boot-starter-remote-shell | 添加遠程 SSH 支持 |
spring-boot-starter-jetty | 使用 Jetty 而不是默認的 Tomcat 做爲應用服務器。 |
spring-boot-starter-log4j | 添加 Log4j 的支持 |
spring-boot-starter-logging | 使用 Spring Boot 默認的日誌框架 Logback |
spring-boot-starter-tomcat | 使用 Spring Boot 默認的 Tomcat 做爲應用服務器。 |
Ø POM 文件中能夠看到,應用所聲明的依賴不多
Ø 只有一個「org.springframework.boot:spring-boot-starter-web」
Ø 而不是像其餘 Spring 項目同樣須要聲明不少的依賴。
Ø 當使用 Maven 命令「mvn dependency:tree」來查看項目實際的依賴時
Ø 發現其中包含SpringMVC框架、SLF4J、Jackson、Hibernate Validator 和 Tomcat 等依賴。
Ø 這實際上 Spring 推薦的 Web 應用中使用的開源庫的組合。
Ø EnableAutoConfiguration」註解的做用在於讓 Spring Boot 根據應用所聲明的依賴來對 Spring 框架進行自動配置,這就減小了開發人員的工做量。
Ø Spring Boot 推薦採用基於 Java 註解的配置方式,而不是傳統的 XML。只須要在主配置 Java 類上添加「@EnableAutoConfiguration」註解就能夠啓用自動配置。
Ø 註解「@RestController」和」@RequestMapping」由 Spring MVC 提供,用來建立 REST 服務。這兩個註解和 Spring Boot 自己並無關係。
在咱們開發Web應用的時候,須要引用大量的js、css、圖片等靜態資源。
Spring Boot默認提供靜態資源目錄位置需置於classpath下,目錄名需符合以下規則:
/static
/public
/resources
/META-INF/resources
舉例:咱們能夠在src/main/resources/目錄下建立static/imgs,在該位置放置一個圖片文件。啓動程序後,嘗試訪問http://localhost:8080/imgs/d.jpg,訪問時不用加static目錄。如能顯示圖片,配置成功。
@RestController public class UserController{ @RestMapping("/login") @ResponseBody public Map<String,Object> login(Sring username,String password){ Map<String,Object> map=new HashMap<String,Object>(); if("季海洋".equals(username) && "123".equal(password)){ map.put("status",true); map.put("info","登錄成功"); }else{ map.put("status",false); map.put("info","用戶名或密碼錯誤"); } return map; } }
@ExceptionHandler
表示攔截異常。@ControllerAdvice
,controller
的一個輔助類,最經常使用的就是做爲全局異常處理的切面類,能夠指定掃描範圍,約定了幾種可行的返回值,若是是直接返回 model 類的話,須要使用
@ResponseBody
進行 json 轉換。
@ControllerAdvice//切面 public class GlobalExceptionHandler { @ExceptionHandler(RuntimeException.class)//捕獲運行時異常 @ResponseBody public Map<String,Object> exceptionHander(){ Map<String, Object> map = new HashMap<String, Object>(); map.put("status",false); map.put("info","系統異常"); return map; } }
在啓動spring中,配置掃描包爲com.jihaiyang.web
@ComponentScan(basePackages="com.jihaiyang.web") @EnableAutoConfiguration public class App{ public static void main(args){ SpringApplication.run(App.class,args); } }
在某個映射的方法中添加個int i=10/0的算術異常
@RestController public class UserController{ @RequestMapping("/login")//映射路徑 @ResponseBody//響應體-自動返回json格式字符串 public Map<String,Object> login(String username,String password){ int i=10/0; Map<String,Object> map=new HashMap<String,Object>(); if("jihaiyang".equals(username) && "123".equals(password)){ map.put("status",true); map.put("info","登陸成功!"); }else{ map.put("status",false); map.put("info","登陸失敗!"); } return map; }; }
模板引擎
在動態HTML實現上Spring Boot依然能夠完美勝任,而且提供了多種模板引擎的默認配置支持,因此在推薦的模板引擎下,咱們能夠很快的上手開發動態網站。
Spring Boot提供了默認配置的模板引擎主要有如下幾種:
1 Thymeleaf
2 FreeMarker
3 Velocity
4 Groovy
5 Mustache
Springboot+freemarker
Spring Boot建議使用這些模板引擎,避免使用JSP,若必定要使用JSP將沒法實現Spring Boot的多種特性,具體可見後文:支持JSP的配置
當你使用上述模板引擎中的任何一個,它們默認的模板配置路徑爲:src/main/resources/templates。固然也能夠修改這個路徑,具體如何修改,可在後續各模板引擎的配置屬性中查詢並修改。
<!-- 引入freeMarker的依賴包. --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
@Controller//若是訪問freemarker模板,就不要用RestController @RequestMapping("/stu") public class StudentController{ @RequestMapping("/list") public String list(Map data){ HashMap data=new HashMap(); //添加數據 data.put("loginname","jihaiyang"); data.put("age",32); ArrayList arrayList = new ArrayList(); String[][] strings = { new String[]{"1001","張三","男"}, new String[]{"1002","李四","男"}, new String[]{"1003","王五","男"}, new String[]{"1004","趙六","男"} }; for (String[] string : strings) { HashMap hashMap = new HashMap(); hashMap.put("id",string[0]); hashMap.put("name",string[1]); hashMap.put("gender",string[2]); arrayList.add(hashMap); } data.put("stuList",arrayList); return "stu/list"; } }
Ø 在src/main/resources/建立一個templates/stu文件夾,後綴爲*.ftl
Ø 掌握如何取值和判斷
list.ftl文件
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title></title> </head> <body> 歡迎${loginname} <#if age <= 17>小哥 <#elseif age <= 30>先生 <#else>大叔 </#if>登陸 <table border="1"> <tr> <td>ID</td> <td>名字</td> <td>性別</td> </tr> <#list stuList?sort_by("id")?reverse as stu> <tr> <td> ${stu.id}</td> <td> ${stu.name}</td> <td> ${stu.gender}</td> </tr> </#list> </table> </body> </html>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent> <dependencies> <!-- SpringBoot 核心組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> </dependencies>
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
@Controller @EnableAutoConfiguration @RequestMapping("/teacher") public class TeacherController{ @RequestMapping("/list") public String list(){ return "list"; } public static void main(String[] args){ SpringApplication.run(TeacherController.class,args); } }
application.properties中設置內容以下
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
<!-- JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
#視圖配置
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
#數據庫配置
spring.datasource.url=jdbc:mysql://localhost:3306/day12
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
在com.jihaiyang.service.impl中編寫
@Service private void registerUser(String username,String password,String email){ @Autowired private JdbcTemplate jdbcTemplate; String sql ="insert into user(username,password,email) values(?,?,?)"; jdbcTemplate.update(sql,username,password,email); }
在com.jihaiyang.web.controller編寫
@Controller @RequestMapping("/user") public class UserController{ @Autowire IUservice userService; @RequestMapping("/register") @ResponseBody public String register(){ userService.registerUser("root","root","root"); return "success"; } }
在com.jihaiyang.app中編寫
@ComponentScan(basePackage={"com.jihaiyang.web","com.jihaiyang.service"}) @EnableAutoConfiguration public class App{ public static void main(String[] args){ SpringApplication.run(App.class,args) ; } }
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 單元測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mybaties --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
application.properties文件的配置以下
#數據庫配置
spring.datasource.url=jdbc:mysql://localhost:3306/
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
6.2.4 Mapper
com.jihaiyang.Mapper中編寫Mapper接口
public interface UserMapper{ @Insert("insert into user(username,password) values(#{username},#{password}") public void save(@Param("username") String username,@Param("password") String password) @Select("select * from user where username=#{username}") public User findByUsername(@Param("username") String username); }
※※※※※※※※※※※※
換成xml形式,將這個放入Maper包中
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.jihaiyang.mapper.UserMapper" > <insert id="save"> insert into t_user (username,password) VALUES(#{0},#{1}) </insert> <select id="findByUsername" resultType="com.gyf.model.User" parameterType="string"> select * from t_user where username = #{username,jdbcType=VARCHAR} </select> </mapper>
注意這裏須要在pom中添加下面代碼
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build>
※※※※※※※※※※※※
package com.jihaiyang.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.gyf.mapper.UserMapper; import com.gyf.model.User; @Controller @RequestMapping("/user") public class UserController { @Autowired private UserMapper userMapper; @RequestMapping("/find") @ResponseBody public User find(String name){ return userMapper.findByName(name); } @ResponseBody @RequestMapping("/add") public int add(String name){ return userMapper.insert(name,"e10adc3949ba59abbe56e057f20f883e"); } }
package com.jihaiyang.app; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages={"com.gyf.controller"}) @MapperScan(basePackages={"com.gyf.mapper"})//掃描Mapper @EnableAutoConfiguration public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
只須要加個Transactional註解便可
@Transaction public class UserServiceImpl implements IUserService{ @Autowired private UserMapper userMapper; @Override public void register(String username,String password){ userMapper.save(username,password); int i=10/0; } }
之前是在applicationContext.xml中配置數據源,如今咱們經過註解來配置數據源,在com.jihaiyang包下建立包datasource包
spring.datasource.test1.driverClassName=com.mysql.jdbc.Driver spring.datasource.test1.url=jdbc:mysql://localhost:3306/dbfirst?useUnicode=true&characterEncoding=utf-8 spring.datasource.test1.username=root spring.datasource.test1.password=123456 spring.datasource.test2.driverClassName=com.mysql.jdbc.Driver spring.datasource.test2.url=jdbc:mysql://localhost:3306/dbsecond?useUnicode=true&characterEncoding=utf-8 spring.datasource.test2.username=root spring.datasource.test2.password=123456
數據庫SQL語句以下
use dbone; CREATE table user( id int PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50), password VARCHAR(50), email VARCHAR(50), birthday TIMESTAMP ); use dbsecond; CREATE table customer( id int PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), tel VARCHAR(50) );
dbone數據庫的數據源配置信息
@Configuration//註解到springboot容器中 @MapperScan(basePackages="com.jihaiyang.dbFirst.mapper",sqlSessionFactoryRef="dbFirstSqlSessionFactory") public class DataSource01 { /** * @return 返回dbFirst數據庫的數據源 */ @Bean(name="dbFirstDataSource") @Primary//主數據源 @ConfigurationProperties(prefix="spring.datasource.dbFirst") public DataSource dateSource(){ return DataSourceBuilder.create().build(); } /** * @return 返回dbFirst數據庫的會話工廠 */ @Bean(name = "dbFirstSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("dbFirstDataSource") DataSource ds) throws Exception{ SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); return bean.getObject(); } /** * @return 返回dbFirst數據庫的事務 */ @Bean(name = "dbFirstTransactionManager") @Primary public DataSourceTransactionManager transactionManager(@Qualifier("dbFirstDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * @return 返回dbFirst數據庫的會話模版 */ @Bean(name = "dbFirstSqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("dbFirstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
dbtwo數據庫的數據源配置信息
@Configuration//註解到springboot容器中 @MapperScan(basePackages = "com.jihaiyang.dbSecond.mapper", sqlSessionFactoryRef = "dbSecondSqlSessionFactory") public class DataSource02 { /** * @return 返回dbSecond數據庫的數據源 */ @Bean(name = "dbSecondDataSource") @ConfigurationProperties(prefix = "spring.datasource.dbSecond") public DataSource dateSource() { return DataSourceBuilder.create().build(); } /** * @return 返回dbSecond數據庫的會話工廠 */ @Bean(name = "dbSecondSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("dbSecondDataSource") DataSource ds) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); return bean.getObject(); } /** * @return 返回dbSecond數據庫的事務 */ @Bean(name = "dbSecondTransactionManager") public DataSourceTransactionManager transactionManager(@Qualifier("dbSecondDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * @return 返回dbSecond數據庫的會話模版 */ @Bean(name = "dbSecondSqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("dbSecondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
public interface CustomerMapper{ @Insert("insert into customer(name,phone) values(#{name},#{telphone})") int insert(@Param("name") String name,@Param("telphone") String telphone) } @Service public class CustomerService{ @Autowired private CustomerMapper customerMapper; /* *添加一個客戶 */ public void add(String name,String telphone){ customerMapper.insert(name,telphone); } }
@Controller @RequestMapper("/user") public class UserController{ @Autowired private UserService userservice; @Autowired private CustomerService customerService; @ResponseBody @RequestMapping("/add") public String add(String name){ userService.register(name,"123"); customerService.add(name,"110"); return "success"; } }
@ComponentScan(basePackages={"com.jihaiyang.datasource","com.jihaiyang.dbone","com.jihaiyang.dbtwo"}) @EnableAutoConfiguration public class App{ public static void main(String[] args){ SpringApplication.run(App.class,args) } }
驗證代碼就不敲了,結論是一個事務只對當前的數據源有效。
使用springboot+jta+atomikos 分佈式事物管理解決方案
6.6.1 添加jta依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
6.6.2 修改數據庫鏈接配置數據
# Mysql 1 mysql.datasource.dbfirst.url = jdbc:mysql://localhost:3306/dbone?useUnicode=true&characterEncoding=utf-8 mysql.datasource.dbfirst.username = root mysql.datasource.dbfirst.password = 123456 mysql.datasource.dbfirst.minPoolSize = 3 mysql.datasource.dbfirst.maxPoolSize = 25 mysql.datasource.dbfirst.maxLifetime = 20000 mysql.datasource.dbfirst.borrowConnectionTimeout = 30 mysql.datasource.dbfirst.loginTimeout = 30 mysql.datasource.dbfirst.maintenanceInterval = 60 mysql.datasource.dbfirst.maxIdleTime = 60 mysql.datasource.dbfirst.testQuery = select 1 # Mysql 2 mysql.datasource.dbsecond.url =jdbc:mysql://localhost:3306/dbsecond?useUnicode=true&characterEncoding=utf-8 mysql.datasource.dbsecond.username =root mysql.datasource.dbsecond.password =123456 mysql.datasource.dbsecond.minPoolSize = 3 mysql.datasource.dbsecond.maxPoolSize = 25 mysql.datasource.dbsecond.maxLifetime = 20000 mysql.datasource.dbsecond.borrowConnectionTimeout = 30 mysql.datasource.dbsecond.loginTimeout = 30 mysql.datasource.dbsecond.maintenanceInterval = 60 mysql.datasource.dbsecond.maxIdleTime = 60 mysql.datasource.dbsecond.testQuery = select 1
6.6.3 添加2個配置模型
@ConfigurationProperties("mysql.datasource.dbfirst") public class DBConfig1 { private String url; private String username; private String password; private int minPoolSize; private int maxPoolSize; private int maxLifetime; private int borrowConnectionTimeout; private int loginTimeout; private int maintenanceInterval; private int maxIdleTime; private String testQuery; }
dbSecond數據源模型
@ConfigurationProperties("mysql.datasource.dbsecond") public class DBConfig2 { private String url; private String username; private String password; private int minPoolSize; private int maxPoolSize; private int maxLifetime; private int borrowConnectionTimeout; private int loginTimeout; private int maintenanceInterval; private int maxIdleTime; private String testQuery; }
6.6.4 設定兩個數據源具體的參數
dbfirst數據庫的數據源
package com.jihaiyang.datasource; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.atomikos.jdbc.AtomikosDataSourceBean; import com.jihaiyang.dbconfig.DBConfig1; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; @Configuration//註解到springboot容器中 @MapperScan(basePackages = "com.jihaiyang.dbFirst.mapper", sqlSessionFactoryRef = "dbFirstSqlSessionFactory") public class DataSource01 { // 配置數據源 @Primary @Bean(name = "dbFirstDataSource") public DataSource testDataSource(DBConfig1 testConfig) throws SQLException { MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(testConfig.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(testConfig.getPassword()); mysqlXaDataSource.setUser(testConfig.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("dbFirstDataSource"); xaDataSource.setMinPoolSize(testConfig.getMinPoolSize()); xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize()); xaDataSource.setMaxLifetime(testConfig.getMaxLifetime()); xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout()); xaDataSource.setLoginTimeout(testConfig.getLoginTimeout()); xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval()); xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime()); xaDataSource.setTestQuery(testConfig.getTestQuery()); return xaDataSource; } @Bean(name = "dbFirstSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("dbFirstDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "dbFirstSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("dbFirstSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
dbsecond數據庫的數據源
package com.jihaiyang.datasource; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.atomikos.jdbc.AtomikosDataSourceBean; import com.gyf.dbconfig.DBConfig2; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; @Configuration//註解到springboot容器中 @MapperScan(basePackages = "com.gyf.dbSecond.mapper", sqlSessionFactoryRef = "dbSecondSqlSessionFactory") public class DataSource02 { // 配置數據源 @Bean(name = "dbSecondDataSource") public DataSource testDataSource(DBConfig2 testConfig) throws SQLException { MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(testConfig.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(testConfig.getPassword()); mysqlXaDataSource.setUser(testConfig.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("dbSecondDataSource"); xaDataSource.setMinPoolSize(testConfig.getMinPoolSize()); xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize()); xaDataSource.setMaxLifetime(testConfig.getMaxLifetime()); xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout()); xaDataSource.setLoginTimeout(testConfig.getLoginTimeout()); xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval()); xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime()); xaDataSource.setTestQuery(testConfig.getTestQuery()); return xaDataSource; } @Bean(name = "dbSecondSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("dbSecondDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "dbSecondSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("dbSecondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
注意,複製時要把每一行後面的空格去除
log4j.rootLogger=INFO,Console,File log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Target=System.out log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n log4j.appender.File=org.apache.log4j.RollingFileAppender log4j.appender.File.File=C:/Users/10301/Desktop/test/logs/info/info.log log4j.appender.File.MaxFileSize=10MB log4j.appender.File.Threshold=ALL log4j.appender.File.layout=org.apache.log4j.PatternLayout log4j.appender.File.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c - %L]%m%n
去除springboot的logging,添加log4j,由於自帶的logging不啓效果
springboot下的Log4j的版本最新1.3.8,若是你的springboot的parent版本太高,那在在添加log4j本身版本 。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusiions> <exclusion> <groupID>org.springframework.boot</groupID> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusiions> </dependency>
添加本身的log4j版本
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j</artifactId> <version>1.3.8 RELEASE</version> </dependency>
7.3 測試
@Autowired private UserService userService; Logger logger=Logger.getLogger(UserService.class); @ResponseBody @RequestMapping("/add") public String add(String name){ logger.info("this is test information !"+"@@Hello :"+name); return "success"; }
<!-- AOP --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
package com.jihaiyang.aop; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @Aspect @Component public class WebLogAspect { private Logger logger = Logger.getLogger(getClass()); @Pointcut("execution(public * com.gyf.controller..*.*(..))") public void webLog() { } @Before("webLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { // 接收到請求,記錄請求內容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 記錄下請求內容 logger.info("---------------request----------------"); logger.info("URL : " + request.getRequestURL().toString()); logger.info("HTTP_METHOD : " + request.getMethod()); logger.info("IP : " + request.getRemoteAddr()); Enumeration<String> enu = request.getParameterNames(); while (enu.hasMoreElements()) { String name = (String) enu.nextElement(); logger.info("name:" + name + "value" + request.getParameter(name)); } } @AfterReturning(returning = "ret", pointcut = "webLog()") public void doAfterReturning(Object ret) throws Throwable { logger.info("---------------response----------------"); // 處理完請求,返回內容 logger.info("RESPONSE : " + ret); } }
Step3:App
在App類中添加對該AOP類的掃描
server.port=8888
server.context-path=/test
注意冒號後的只能用空格,不能用tab
server: port: 8090 context-path: /test-yml
先打成war包或者jar包
使用java -jar test3-0.0.1-SNAPSHOT.jar 運行便可
打包時添加下面依賴代碼
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.gyf.app.App</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>