SpringBoot分散式管理,新增日誌記錄,註解配置與EhCache使用
阿新 • • 發佈:2018-12-31
首先看下專案結構:
首先看下pom.xml配置的jar包:
application.properties裡面配置資料庫的連結資訊<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>SpringBootTest</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <!-- 引入繼承SpringBoot,實現jar的依賴管理 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> <relativePath/> </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-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Spring-Mybatis --> <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> <!-- 引入springboot+jta+atomikos幫助管理事務,可以完成事務回滾 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <!-- 使用AOP統一處理Web請求日誌 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 快取EhCache使用 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <version>2.5</version> </configuration> </plugin> </plugins> </build> </project>
DBConfig1,這個檔案的作用設計把資料庫的配置資訊全部拿過來用atomikos進行分散式管理:spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp # Mysql 1 mysql.datasource.test.url = jdbc:mysql://192.168.10.205:3306/test1 mysql.datasource.test.username = root mysql.datasource.test.password = root mysql.datasource.test.minPoolSize = 3 mysql.datasource.test.maxPoolSize = 25 mysql.datasource.test.maxLifetime = 20000 mysql.datasource.test.borrowConnectionTimeout = 30 mysql.datasource.test.loginTimeout = 30 mysql.datasource.test.maintenanceInterval = 60 mysql.datasource.test.maxIdleTime = 60 # Mysql 2 mysql.datasource.test2.url =jdbc:mysql://192.168.10.205:3306/test2 mysql.datasource.test2.username =root mysql.datasource.test2.password =root mysql.datasource.test2.minPoolSize = 3 mysql.datasource.test2.maxPoolSize = 25 mysql.datasource.test2.maxLifetime = 20000 mysql.datasource.test2.borrowConnectionTimeout = 30 mysql.datasource.test2.loginTimeout = 30 mysql.datasource.test2.maintenanceInterval = 60 mysql.datasource.test2.maxIdleTime = 60
WebLogAspect:這裡面是定義日誌的內容:package com.config; import org.springframework.boot.context.properties.ConfigurationProperties; /** * *類描述:讀取application.properties資料來源1的配置資訊,如使用者名稱,密碼等 *@author: blank *@date: 日期:2018-1-24 時間:上午8:56:59 * */ @ConfigurationProperties(prefix = "mysql.datasource.test") 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; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } 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; } public int getMinPoolSize() { return minPoolSize; } public void setMinPoolSize(int minPoolSize) { this.minPoolSize = minPoolSize; } public int getMaxPoolSize() { return maxPoolSize; } public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; } public int getMaxLifetime() { return maxLifetime; } public void setMaxLifetime(int maxLifetime) { this.maxLifetime = maxLifetime; } public int getBorrowConnectionTimeout() { return borrowConnectionTimeout; } public void setBorrowConnectionTimeout(int borrowConnectionTimeout) { this.borrowConnectionTimeout = borrowConnectionTimeout; } public int getLoginTimeout() { return loginTimeout; } public void setLoginTimeout(int loginTimeout) { this.loginTimeout = loginTimeout; } public int getMaintenanceInterval() { return maintenanceInterval; } public void setMaintenanceInterval(int maintenanceInterval) { this.maintenanceInterval = maintenanceInterval; } public int getMaxIdleTime() { return maxIdleTime; } public void setMaxIdleTime(int maxIdleTime) { this.maxIdleTime = maxIdleTime; } public String getTestQuery() { return testQuery; } public void setTestQuery(String testQuery) { this.testQuery = testQuery; } }
package com.controller;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 = LoggerFactory.getLogger(getClass());
@Pointcut("execution(public * com.controller..*.*(..))")//插入的地方
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到請求,記錄請求內容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄下請求內容
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:{},value:{}", name, request.getParameter(name));
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 處理完請求,返回內容
logger.info("RESPONSE : " + ret);
}
}
IndexController:主類中裡面應註解對各個方法進行呼叫:
package com.controller;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.test01.mapper.UserMapper01;
import com.test02.mapper.UserMapper02;
@RestController
public class IndexController {
//使用日誌
private static Logger log=Logger.getLogger(IndexController.class);
@Autowired
private CacheManager cacheManager;
//自定義數值
// @Value("${name}")
// private String name;
@Autowired
private UserMapper01 userMapper1;
@Autowired
private UserMapper02 userMapper2;
@RequestMapping("/adduser")
public String adduser(String name, Integer age) {
userMapper1.insertUsers("大腸", 22);
userMapper2.insertUsers("阿幹", 33);
return "success";
}
//寫日誌
@RequestMapping("/log")
public String log(){
log.info("test log");
return "success";
}
@ResponseBody
@RequestMapping("/addUserName")
public String addUserName(String name){
return "success";
}
//查詢語句
@ResponseBody
@RequestMapping("/selectusers")
public String getUsers(Integer id){
return userMapper1.findUsersByid(id).toString();
}
//清除快取
@ResponseBody
@RequestMapping("/remoKey")
public String remoKey() {
cacheManager.getCache("baseCache").clear();
return "success";
}
//自定義數值
// @ResponseBody
// @RequestMapping("/getValue")
// public String getValue() {
// return name;
// }
}
TestMyBatisConfig1,配置資料來源資訊(把資料來源資訊交給Atomikos來處理):
package com.datasources;
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.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.config.DBConfig1;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
@Configuration
//basePackages 最好分開配置 如果放在同一個資料夾可能會報錯
@MapperScan(basePackages = "com.test01", sqlSessionTemplateRef = "testSqlSessionTemplate")
public class TestMyBatisConfig1 {
// 配置資料來源
@Primary
@Bean(name = "testDataSource")
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("testDataSource");
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 = "testSqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "testSqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
Users實體:package com.model;
public class Users {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
UserMapper01,對資料庫1進行操作
package com.test01.mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import com.model.Users;
@CacheConfig(cacheNames = "baseCache")
public interface UserMapper01 {
@Select("select * from users where id=#{id}")
@Cacheable
Users findUsersByid(@Param("id")Integer id);
// @Select("select * from users")
// @Cacheable
// Users selectallUsers();
@Insert("insert into users values(null,#{name},#{age});")
int insertUsers(@Param("name")String name,@Param("age")Integer age);
}
service層:package com.test01.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.test01.mapper.UserMapper01;
@Service
public class UserService01 {
@Autowired
private UserMapper01 userMapper1;
//事務回滾,如果這部分出錯,將會回滾
@Transactional
public int addUser(String name,Integer age){
return userMapper1.insertUsers(name, age);
}
}
log4j.properties這裡是配置日誌:
#log4j.rootLogger=CONSOLE,info,error,DEBUG
log4j.rootLogger=info,error,CONSOLE,DEBUG
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.info.datePattern='.'yyyy-MM-dd
log4j.appender.info.Threshold = info
log4j.appender.info.append=true
#log4j.appender.info.File=/home/admin/pms-api-services/logs/info/api_services_info
log4j.appender.info.File=/Users/dddd/Documents/testspace/pms-api-services/logs/info/api_services_info
log4j.logger.error=error
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.error.datePattern='.'yyyy-MM-dd
log4j.appender.error.Threshold = error
log4j.appender.error.append=true
#log4j.appender.error.File=/home/admin/pms-api-services/logs/error/api_services_error
log4j.appender.error.File=/Users/dddd/Documents/testspace/pms-api-services/logs/error/api_services_error
log4j.logger.DEBUG=DEBUG
log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.DEBUG.datePattern='.'yyyy-MM-dd
log4j.appender.DEBUG.Threshold = DEBUG
log4j.appender.DEBUG.append=true
#log4j.appender.DEBUG.File=/home/admin/pms-api-services/logs/debug/api_services_debug
log4j.appender.DEBUG.File=/Users/dddd/Documents/testspace/pms-api-services/logs/debug/api_services_debug
ehcache.xml:配置快取<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<!-- 預設配置 -->
<defaultCache maxElementsInMemory="5000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
memoryStoreEvictionPolicy="LRU" overflowToDisk="false" />
<cache name="baseCache" maxElementsInMemory="10000"
maxElementsOnDisk="100000" />
</ehcache>
最後來到主程式:
APP:
package com.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import com.config.DBConfig1;
import com.config.DBConfig2;
//有多個專案的時候,要加入這個註解,用來掃描包,掃描service層和dao層
@ComponentScan(basePackages={"com.controller","com.config","com.datasources","com.test01","com.test02"})
//開啟快取註解
@EnableCaching
//開啟定時任務註解
//@EnableScheduling
//只能使用者一個註解
@EnableAutoConfiguration
//開啟讀取這兩個配置檔案
@EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
最後啟動。