SpringBoot技术点细解
SpringBoot(主流)
SpringBoot简介
核心点:
1、敏捷开发,轻量级框架 , 弊端:封装太完美,不方便扩展 (但是高版本中的springboot是可以自定义的)
2、无需tomcat (java应用程序运行,通过运行jar包)
3、减少xml配置(几乎没有xml),配置properties文件
4、SpringCloud + SpringBoot = (微服务开发)
5、注解
SpringBoot与微服务有什么关联?
目前微服务都是使用springCloud(Http接口+rest),SpringCloud用的是SpirngbBoot,SpringBoot Web组件封装SpringMVC。
SpringBoot的底层是SpringMVC,所以SpringBoot不可能和Struts整合。
互联网项目的趋势:面向服务架构(SOA) --》 微服务架构 (SpringCloud+SpringBoot)
SpringData 与 SpringMVC
SpringData主要用来操作数据库,类似mybatis、hibernate
SpringMVC是控制层框架
SpringBoot是否安全?
安全,封装的比较好。
核心依赖:
引入父类工程:自动将常用的依赖包引用过了了
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEALSE</version>
</parent>
引入web组件:自动引用spring 引用SpringMVC,不写版本,自动解决jar包冲突问题
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
springboot封装jar包的依赖原理:(为什么加一个依赖就能引入所有相关jar包)
使用maven继承依赖关系,管理所有的jar包。
引用指定的jar包,然后自动的引用其它相关jar包。
@RestController:返回json格式的数据
@RestController 类似于 @Controller + @ResponseBody
@EnableAutoConfiguration :创建tomcat容器,注入所有配置信息
主方法: main,标识开始运行该项目
启动成功后,端口号为8080
SpringBoot如果有多个controller类,可以新建一个启动类(包含mainfnagf )。
在启动类上使用 @ComponentScan("cn.demo.controller") 扫描所有的controller类
SpringBoot项目启动后,可以直接访问静态资源
静态资源推荐放在src/java/resources目录下的,static(自己新建的目录)下,可以通过
http://localhost:8080/pic.jpg访问图片
全部捕获异常:(管理整个项目的异常,改变404/500错误页面)
(1)新建全局捕获异常类 使用@ControllerAdvice
当项目中出现运行时异常时。。会自动调用此方法,然后返回到相应的页面。
/**
* 全部捕获异常:使用AOP的异常通知
* @author Administrator
*如果返回json格式 添加@ResponseBody注解,
*如果返回页面使用String作为返回值,不需要添加注解
*/ @ControllerAdvice
public class GlobalExceptionHandler { //以json数据返回
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Map<String,Object> error500(){
Map<String,Object> map = new HashMap<String,Object>();
map.put("500", "系统错误");
return map;
} // //异常是返回页面
// @ExceptionHandler(RuntimeException.class)
// public String error404(){
// return "error";
// } }
Springboot和freemarker整合:
Springboot和模板引擎整合,不推荐使用jsp。推荐 freemarker
模板引擎(动态页面静态化):将动态的数据未造成静态的html页面
优点: 提高搜索引擎搜索效率,静态页面会排前
能做动态Active实现
模板引擎技术: Freemarker、velocity、thymelef
SpringBoot怎么渲染页面?
(1)加入freemarker依赖
spring-boot-starter-freemarker
(2)freemarker默认找的是resources/templates 目录下的文件
在sourcess/templates 目录下新建 index.ftl 页面
(3)使用@Controller注解,返回String类型数据
可以不加任何配置,直接启动就行了。(也可以配置aplication.properties文件)
pom.xml文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!—SpringBoot web 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--springboot 整合freemarker 添加的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
</dependencies>
freemarker在application.properteis中的配置:
spring.freemarker.allow-request-override=false spring.freemarker.cache=true spring.freemarker.check-template-location=true spring.freemarker.charset=UTF-8 spring.freemarker.content-type=text/html spring.freemarker.expose-request-attributes=false spring.freemarker.expose-session-attributes=false spring.freemarker.expose-spring-macro-helpers=false #spring.freemarker.prefix= #spring.freemarker.request-context-attribute= #spring.freemarker.settings.*= spring.freemarker.suffix=.ftl #配置freemarker文件的位置
spring.freemarker.template-loader-path=classpath:/templates/ #comma-separated list #spring.freemarker.view-names= # whitelist of view names that can be resolved
SpringBoot整合jsp项目
(1)一定要选择war包,maven项目
(2)引入jsp依赖: spring-boot-starter-tomcat ,spring-boot-starter-web,tomcat-embed-jasper
(3)使用@Controller注解,返回String类型数据
(4)在application.properteis文件中配置:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
pom.xml文件
<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>
SpringBoot整合JdbcTemplate
(1)引入依赖 spring-boot-starter-jdbc,spring-boot-starter-test,mysql-connector-java
(2)建立application.properties文件 ,配属数据库信息
(3)在业务层, @Autoworied private JdbcTemplate jdbcTemplate; jdbcTemplate.update("数据库语句");
pom.xml文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<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.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
main法对应的类中,扫多个包
@ComponentScan(basePackage{"com.demo.controller","com.demo.service"})
SpringBoot整合JPA
SpringJPA:对hibernate做封装,基本上使用注解。
项目整合jdbc/jpa/mybatis不会有冲突,所以依赖不会冲突
(1)引入依赖 spring-boot-data-jpa,mysql-connector-java
(2)创建实体类 ,使用注解@Entity(name="user")--引用java中的,不要引用hiberante里面的
@Id 标识主键,@Column 标识为列
(3)建立application.properties文件 ,配属数据库信息
(4)新建Dao层,集成JpaRepository。public interface UserDao extends
JpaRepository<User,Integer>{},
@Autoworied
private UserDao userDap;
userDao.save("数据库语句");//增加
userDao.find(id);//删除
(5)添加 EnableJpaRepositories("com.demo.dao") //扫描到层
(6)添加EntityScan("com.demo.bean") //扫描实体类
SpringBoot整合Mybatis
(1)加入依赖 mybatis-spring-boot-starter
(2)加入applcation.properties 配置文件,数据库配置信息
mybatis 注解版本 和 XML版本
注解版本
新建mapper接口,UserMapper.java
例如:@Select("{SELECT *FROM USER WHERE NAME=#{name}}")
User findByName(@Param("name") String name);
在main主类中使用注解: @MapperScan("com.demo.mapper")
运行springboot时记得注明tomcat的版本,如果本地tomcat的版本为8.0以下时
通过添加依赖:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>7.0.72</version> <!--这个就是tomcat的版本-->
</dependency>
springboot整合使用springjpa
pom文件引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<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.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
创建User实体类
@Entity(name = "users")
public class User {
@Id
@GeneratedValue
private Integer id;
@Column
private String name;
@Column
private Integer age;
// ..get/set方法
}
创建UserDao 这里继承了JpaRepository就可以直接使用了,里面有基本的增删改查方法
public interface UserDao extends JpaRepository<User, Integer> {}
创建IndexController
@RestController
public class IndexController {
@Autowired
private UserDao userDao;
@RequestMapping("/index")
public String index(Integer id) {
User findUser = userDao.findOne(id);
System.out.println(findUser.getName());
return "success";
}
}
启动项目 需要添加注解:
@EnableJpaRepositories(basePackages = "com.dao") //扫描到dao层
@EntityScan(basePackages = "com.entity") //扫描实体类层
@ComponentScan(basePackages = { "com" })
@EnableJpaRepositories(basePackages = "com.dao")
@EnableAutoConfiguration
@EntityScan(basePackages = "com.entity")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
springboot整合多数据源
配置文件中新增两个数据源 application.properties文件中配置:
#数据源test1
spring.datasource.test1.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test1.url = jdbc:mysql://localhost:3306/test01?
useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = root #数据源test2
spring.datasource.test2.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test2.url = jdbc:mysql://localhost:3306/test02?
useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = root
自定义数据源配置:
@Bean(name = "test1DataSource") //创建name为test1DataSource的bean
@Qualifier("test1DataSource") //表示引用 test1DataDource
@Primary //这个注解指定默认的数据源信息
@ConfigurationProperties(prefix = "spring.datasource.test1") //读取application.properteis配置文件中的前缀为 spring.datasource.test1的配置信息
@Configuration // 注册到springboot容器中
@MapperScan(basePackages = "com.user1", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config { /**
*
* @methodDesc: 功能描述:(配置test1数据库)
*/
@Bean(name = "test1DataSource")
@Primary //这个注解指定默认的数据源信息
@ConfigurationProperties(prefix = "spring.datasource.test1") //读取application.properteis配置文件中的前缀为 spring.datasource.test1的配置信息
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
} /**
*
* @methodDesc: 功能描述:(test1 sql会话工厂)
*/
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 如果不是注解开发就需要使用下面这个设置,来注明mapper.xml文件的位置
// bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
return bean.getObject();
} /**
*
* @methodDesc: 功能描述:(test1 事物管理)
*/
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} @Bean(name = "test1SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
} }
创建分包Mapper ,与数据源配置的@MapperScan注解里面的信息对应。
public interface User1Mapper {
@Insert("insert into users values(null,#{name},#{age});")
public int addUser(@Param("name") String name, @Param("age") Integer age);
}
启动项目
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
事物管理
springboot整合事物管理
springboot默认集成事物,只主要在方法上加上@Transactional即可
SpringBoot分布式事物管理
使用springboot+jta+atomikos 分布式事物管理
pom.xml,添加如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
application.properties
# Mysql 1
mysql.datasource.test.url = jdbc:mysql://localhost:3306/test01?
useUnicode=true&characterEncoding=utf-8
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.datasource.test.testQuery = select 1 # Mysql 2
mysql.datasource.test2.url =jdbc:mysql://localhost:3306/test02?
useUnicode=true&characterEncoding=utf-8
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
mysql.datasource.test2.testQuery = select 1
读取配置文件信息
package com.config; import org.springframework.boot.context.properties.ConfigurationProperties; @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;
} package com.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "mysql.datasource.test1")
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;
}
创建多数据源
@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);
}
}
package com.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.itmayiedu.config.DBConfig1;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; @Configuration
// basePackages 最好分开配置 如果放在同一个文件夹可能会报错
@MapperScan(basePackages = "com.itmayiedu.test02", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class TestMyBatisConfig2 { // 配置数据源
@Bean(name = "test2DataSource")
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("test2DataSource"); 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 = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
} @Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
在启动类中需要使用@EnableConfigurationProperteis注解来加载配置信息:
@EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })
日志管理
使用log4j记录日志
log4j.properties (这是linux下的日志配置,如果是windows下使用,需要更改文件路径配置)
#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-
使用AOP统一处理Web请求日志
pom.xml文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
使用@Aspect注解标识切面类:
@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);
}
}
缓存支持
注解配置与EhCache使用
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
新建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>
配置信息详解:
<!--
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
代码使用Cacheable
@CacheConfig(cacheNames = "baseCache")
public interface UserMapper {
@Select("select * from users where name=#{name}")
@Cacheable
UserEntity findName(@Param("name") String name);
}
清除缓存
@Autowired
private CacheManager cacheManager;
@RequestMapping("/remoKey")
public void remoKey() {
cacheManager.getCache("baseCache").clear();
}
使用@Scheduled创建定时任务
在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置
@Component
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}
}
使用@Async实现异步调用
(1)在启动类上加上@EnableAsync
(2)需要执行异步方法上加入 @Async
就能实现异步。异步就相当于多线程的执行,不需要等方法执行完在执行下一条语句。
自定义参数
(1)在application.properties文件中添加配置
name=www.com
(2)在Controller类中得到配合文件中的参数值
通过 @Value("${name}") 将配置文件中的信息读取过来
@Value("${name}")
private String name; @ResponseBody
@RequestMapping("/getValue")
public String getValue() {
return name;
}
多环境配置
(1)编写多个配置文件,命名方式为: application-*.properties
application-dev.properties:开发环境
application-test.properties:测试环境
application-pre.properties:预生产环境
application-prod.properties:生产环境
(2)在application.properties文件中指定使用配置文件:
spring.profiles.active=pre #指定使用application-pre.properties --- 预生产环境配置文件
修改端口号
server.port=8888
server.context-path=/Demo
SpringBoot yml 使用
创建application.yml
server:
port: 8090
context-path: /Demo
发布打包
使用mvn package 打包
使用java –jar 包名
如果报错没有主清单,在pom文件中新增
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<maimClass>com.dmeo.app.App</maimClass> //这里指定执行的主类,就是main方法所在的类
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions> </plugin>
</plugins>
</build>
Springboot与redis整合:
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot</groupId>
<artifactId>springboot-redis</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-redis Maven Webapp</name>
<url>http://maven.apache.org</url> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler.source>1.7</compiler.source>
<compiler.target>1.7</compiler.target> <!-- servlet/jsp/EL (2.4/2.0/?)(2.5/2.1/2.1),(3.0/2.2/2.2),(3.1/2.3/3.0) -->
<servlet.version>3.1.0</servlet.version>
<jsp.version>2.3.1</jsp.version>
<jstl.version>1.2</jstl.version>
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</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.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
业务层直接调用StringRedisTemplate:
package springboot.springboot_redis.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; @Service
public class RedisService { @Autowired
private StringRedisTemplate stringRedisTemplate; public void setObject(String key,Object value)
{//redis : hash set zset list string
//先用common-lang包下的 StringUtils 判断key 和value是否为空
if(StringUtils.isEmpty(key) || value == null ){
return ;
} //判断类型: 存放string类型
if(value instanceof String){
String strValue= (String )value;
stringRedisTemplate.opsForValue().set(key, strValue);
return;
} //判断类型: 存放list类型
if(value instanceof List){
List<String> listValue= (List<String>)value;
for(String str : listValue){
stringRedisTemplate.opsForList().leftPush(key, str);
}
return;
} }
}
application.properteis配置信息:
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=1
spring.redis.timeout=5000
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
table.MsoTableGrid
{mso-style-name:网格型;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-priority:59;
mso-style-unhide:no;
mso-style-qformat:yes;
border:solid windowtext 1.0pt;
mso-border-alt:solid windowtext .5pt;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-border-insideh:.5pt solid windowtext;
mso-border-insidev:.5pt solid windowtext;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
mso-pagination:none;
font-size:10.0pt;
font-family:"Times New Roman","serif";}
SpringBoot技术点细解的更多相关文章
- 手把手教你用git和SourceTree上传项目到github细解(转)
尊重原创:https://blog.csdn.net/qq_32365567/article/details/52859166 一.引言 我想大家现在都很熟悉github了,也能运用github上开源 ...
- SpringBoot之DispatcherServlet详解及源码解析
在使用SpringBoot之后,我们表面上已经无法直接看到DispatcherServlet的使用了.本篇文章,带大家从最初DispatcherServlet的使用开始到SpringBoot源码中Di ...
- SpringBoot Profile使用详解及配置源码解析
在实践的过程中我们经常会遇到不同的环境需要不同配置文件的情况,如果每换一个环境重新修改配置文件或重新打包一次会比较麻烦,Spring Boot为此提供了Profile配置来解决此问题. Profile ...
- SpringBoot技术栈搭建个人博客【前台开发/项目总结】
前言:写前台真的是我不擅长的东西...所以学习和写了很久很久...前台页面大概开发了两天半就开发好了,采用的静态的html和bootstrap来写,写后台的时候纠结住了...怎么说呢,写页面真的是头疼 ...
- SpringBoot技术栈搭建个人博客【后台开发】
前言:在之前,我们已经完成了项目的基本准备,那么就可以开始后台开发了,突然又想到一个问题,就是准备的时候只是设计了前台的RESTful APIs,但是后台管理我们同样也是需要API的,那么就在这一篇里 ...
- 【软件笔记】 ◆笔记·I◆ 各类冷门函数细解
[软件笔记·I] 各类冷门函数细解 ■题外话■ 总觉得作为一个志向远大的 coder (٩(◕‿◕。)۶),我觉得单单只会做题是不够的所以我开始尝试自己编写软件!初入道的我并不知道C++其实并不太适合 ...
- 细解JavaScript ES7 ES8 ES9 新特性
题记:本文提供了一个在线PPT版本,方便您浏览 细解JAVASCRIPT ES7 ES8 ES9 新特性 在线PPT ver 本文的大部分内容译自作者Axel Rauschmayer博士的网站,想了解 ...
- Spring全家桶——SpringBoot之AOP详解
Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...
- Springboot mini - Solon详解(四)- Solon的事务传播机制
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
随机推荐
- 【转载】LINUX下安装wget命令(SFTP实现法)
如何安装wget命令. 方法一:通过yum 命令行为:yum install wget 完成.此操作很简单,但是我安装的linux是centos的最小版本,运行上述命令时会出现无法连接到源网站(大概是 ...
- FreeRTOS
一.内核配置 1.configUSE_PREEMPTION 设置为1,使用抢先式内核:设置为0,为合作轮转内核. 2.configCPU_CLOCK_HZ 内部处理器执行的频率.这个值需要正确配置外围 ...
- putty 显示 ubuntu的文件乱码
http://www.linuxidc.com/Linux/2012-01/52252.htm 下面几个注意点 1) Windows - Appearance - Font settings 里可以更 ...
- 差异基因分析:fold change(差异倍数), P-value(差异的显著性)
在做基因表达分析时必然会要做差异分析(DE) DE的方法主要有两种: Fold change t-test fold change的意思是样本质检表达量的差异倍数,log2 fold change的意 ...
- English trip V1 - B 24. I'm Interested in... 我对...感兴趣 Teacher:Julia Key: (I/We/They) do/don't (He/She/it)does/doesn't
In this lesson you will learn to talk about people's interests. 课上内容(Lesson) interest v. 使…感兴趣(inter ...
- CSS3实现烟花特效 --web前端
烟花特效,比较简单,直接贴代码了…… <!DOCTYPE html><html lang="en"><head> <meta charse ...
- Lab 6-1
LABS The goal of the labs for this chapter is to help you to understand the overall functionality of ...
- 搭建智能合约开发环境Remix IDE及使用
目前开发智能的IDE, 首推还是Remix, 而Remix官网, 总是由于各种各样的(网络)原因无法使用,本文就来介绍一下如何在本地搭建智能合约开发环境remix-ide并介绍Remix的使用. 写在 ...
- CF1129C Morse Code
pro: 维护一个01字符串,支持在结尾动态加字符. 每一个长度<=4的01串可以对应一个字母(有几个特例除外) 每次操作后询问,这个字符串的所有子串一共可以对应出多少种本质不同的字符串. so ...
- 2018 USP Try-outsF - Optimizing Transportation in Portugal
题意:给你一副无向图,求使s到t删掉一条的最短路最大的长度 题解:先预处理s,t到每个点的最短路,二分答案,对于一条边,如果选中这条边,那么对于s->u+u->v+v->t或者s-& ...