笔者自学的框架,知识点来自网上学习教程,方便实惠,推荐,特此声明。
(但是没有很多细节,真的很伤啊学起来)
<!-- springboot 开发自动热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
使得springboot支持jsp,让springboot编译webapp下文件,同时在Project Structure中设置web.xml<!--springboot tomcat jsp 支持开启-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>compile</scope>
</dependency>
在built标签下加入<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml
src/main/resources
**/ **</include>
</includes>
</resource>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**
#字符编码位置要放到下面中文的上面,下面是指定字符编码
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
#修改内置tomcat端口号
server.port=8080
#设置项目上下文
server.servlet.context-path=/myspringboot
#设置开发环境得配置文件,优先级比application.properties高
spring.profiles.active=dev
#自定义配置
author.name=java
author.address=广东
author.age=18
例可以设置几种不同的环境开发环境:application-dev.properties
测试环境:application-test.properties
生产环境:application-online.properties
让springboot支持jspspring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
#这个是关闭thymeleaf缓存,不是很必要
spring.thymeleaf.cache=false
#关闭thymeleaf模板,不是很必要
spring.thymeleaf.enabled = false
@Value("${author.name}")
private String author;
2.2 读取配置文件@Component @ConfigurationProperties @PropertySource@Component
@PropertySource(value = "classpath:author.properties")//指定外部配置文件的名字
@ConfigurationProperties(prefix = "author")//前缀,对应的是配置文件中的author
<!-- 加载mybatis整合springboot -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- MySQL的jdbc驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- springboot 开发自动热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml
#指定mapper文件的位置
mybatis.mapper-locations=classpath:com/java/demo/dao/*.xml
#指定bean的位置
mybatis.type-aliases-package=com.java.demo.bean
#数据源
spring.datasource.username=root
spring.datasource.password=passwd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sqldemo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone= Asia/Shanghai
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#查看sql语句日志
logging.level.com.java.demo.dao=debug
<?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.java.demo.dao.StudentMapper">
<!--查询多条数据-->
<select id="selectAllStudent" resultType="student">
SELECT id,name,age,score FROM t_student
</select>
</mapper>
4.2 在dao方法上加上注解。 保存对象,获取数据库自增id @Options(useGeneratedKeys=true, keyProperty=“id”, keyColumn=“id”)@Select("SELECT * FROM user")
@Results({
@Result(column = "create_time",property = "createTime") //javaType = java.util.Date.class
})
List<User> getAll();
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(column = "create_time",property = "createTime")
})
User findById(Long id);
@Update("UPDATE user SET name=#{name} WHERE id =#{id}")
void update(User user);
@Delete("DELETE FROM user WHERE id =#{userId}")
void delete(Long userId);
@SpringBootApplication
@EnableTransactionManagement //开启事务支持
@MapperScan("com.java.demo.dao")//扫描mapper文件
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在访问数据库的Service方法上添加注解 @Transactional(propagation=Propagation.REQUIRED,isolation=)(举例) 即可@Service
@Transactional//开启事务
public class StudentServiceImpl implements StudentService{
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> selectAllStudent() {
System.out.println("测试");
return studentMapper.selectAllStudent();
}
}
characterEncodingFilter
hiddenHttpMethodFilter
httpPutFormContentFilter
requestContextFilter
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("我的拦截器");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
1.2、将拦截器加入到拦截器管理中@Configuration//表示该类会被spring容器创建
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration r1 = registry.addInterceptor(new MyInterceptor());
//添加拦截请求
r1.addPathPatterns("/*");
//添加不拦截的请求
r1.excludePathPatterns("/login");
//上面跟下面的写法是一样的
//registry.addInterceptor(new PermissionInterceptor()).addPathPatterns("/*").excludePathPatterns("/login");
}
}
@WebFilter(urlPatterns="/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("进入filter过滤器");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
然后再Springboot启动类上添加@ServletComponentScan@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean myFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new MyFilter());
registration.addUrlPatterns("/*");
return registration;
}
}
@WebServlet("/myServlet")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = -4134217146900871026L;
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("hello word");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
@SpringBootApplication
@ServletComponentScan(basePackages="com.monkey1024.servlet")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
方式二@Configuration
public class ServletConfig {
@Bean
public ServletRegistrationBean myServletRegistrationBean(){
ServletRegistrationBean registration = new ServletRegistrationBean(new MyServlet(), "/servlet/myServlet");
return registration;
}
}
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加actuator依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--spring boot admin依赖-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
#设置actuator监控端口
management.server.port=8081
#开启所有监控,默认只开启health和info
management.endpoints.web.exposure.include=*
#添加info信息
info.author=java.demo
info.url=www.java.com
http://localhost:8081/actuator/info
使用MultipartFile
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//单个文件最大
factory.setMaxFileSize("10240KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("1024000KB");
return factory.createMultipartConfig();
}
打包成jar包<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.properties中增加下面配置,指定服务器的路径web.images-path=/Users/jack/Desktop
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/test/,file:${web.upload-path}
<!--springboot程序测试依赖,如果是自动创建项目默认添加-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
//使用@RunWith(SpringRunner.class) //底层用junit SpringJUnit4ClassRunner
@SpringBootTest(classes={XdclassApplication.class})//启动整个springboot工程
public class SpringBootTests { }
@AutoConfigureMockMvc
@SpringBootTest(classes={XdclassApplication.class})
@@RunWith(SpringRunner.class)
public class SpringBootTests {
MvcResult mvcResult =mockMvc.perform(MockMvcRequestBuilders.get("/test/home")).andExpect(MockMvcResultMatchers.status().isok()).andReturn();
System.out.printlnn(status);
}
@ControllerAdvice
@ExceptionHandler(value=Exception.class)
可放回modelandview或者Json数据public class XdclassApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(XdclassApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(XdclassApplication.class, args);
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
# 是否开启thymeleaf缓存,本地为false,生产建议为true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.allow-request-override=false
spring.freemarker.check-template-location=true
#类型
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
#文件后缀
spring.freemarker.suffix=.ftl
#路径
spring.freemarker.template-loader-path=classpath:/templates/
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
#开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
spring.thymeleaf.mode=HTML5
#前缀
spring.thymeleaf.prefix=classpath:/templates/
#编码
spring.thymeleaf.encoding=UTF-8
#类型
spring.thymeleaf.content-type=text/html
#名称的后缀
spring.thymeleaf.suffix=.html
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
#=========redis基础配置=========
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6390
# 连接超时时间 单位 ms(毫秒)
spring.redis.timeout=3000
#=========redis线程池设置=========
# 连接池中的最大空闲连接,默认值也是8。
spring.redis.pool.max-idle=200
#连接池中的最小空闲连接,默认值也是0。
spring.redis.pool.min-idle=200
# 如果赋值为-1,则表示不限制;pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
spring.redis.pool.max-active=2000
# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时
spring.redis.pool.max-wait=1000
@Autowired
AsyncTask at =new AsyncTask();
public void demofunction(){
at.task1();
Future<String> result2=at.task2();
if(task2.isDone())
{
//result2完成的操作
}
}
@Async
public void task1() throws InterruptedException
{
Tread.sleep(1000L);
}
@Async
public Future<String> task2() throws InterruptedException
{
Tread.sleep(1000L);
return AsyncResult<String>("task执行完成");
}
<configuration> 子节点
<appender>appender>
<logger>logger>
<root>root>(要加在最后)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
ELASTICSEARCH (ElasticsearchProperties)
spring.data.elasticsearch.cluster-name=elasticsearch # Elasticsearch cluster name.
spring.data.elasticsearch.cluster-nodes=localhost:9300 # Comma-separated list of cluster node addresses.
spring.data.elasticsearch.repositories.enabled=true # Whether to enable Elasticsearch repositories.
一. ActiveMQ
<!-- 整合消息队列ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!-- 如果配置线程池则加入 -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
4.3 application.properties配置 spring.activemq.broker-url=tcp://127.0.0.1:61616
#集群配置
#spring.activemq.broker-url=failover:(tcp://localhost:61616,tcp://localhost:61617)
spring.activemq.user=admin
spring.activemq.password=admin
#下列配置要增加依赖
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=100
#配置信息支持模型开启后不支持点对点而支持多订阅
#default point to point
spring.jms.pub-sub-domain=true
4.4 springboot启动类 @EnableJms,开启支持jms@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(true);
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
然后再注解里添加containerFactory=“jmsListenerContainerTopic”二. RocketMQ
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-common</artifactId>
<version>${rocketmq.version}</version>
</dependency>
6.2application.properties加入配置文件# 消费者的组名
apache.rocketmq.consumer.PushConsumer=orderConsumer
# 生产者的组名
apache.rocketmq.producer.producerGroup=Producer
# NameServer地址
apache.rocketmq.namesrvAddr=127.0.0.1:9876
6.3生产者 /**
* 生产者的组名
*/
@Value("${apache.rocketmq.producer.producerGroup}")
private String producerGroup;
/**
* NameServer 地址
*/
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
private DefaultMQProducer producer ;
public DefaultMQProducer getProducer(){
return this.producer;
}
@PostConstruct
public void defaultMQProducer() {
//生产者的组名
producer = new DefaultMQProducer(producerGroup);
//指定NameServer地址,多个地址以 ; 隔开
//如 producer.setNamesrvAddr("192.168.100.141:9876;192.168.100.142:9876;192.168.100.149:9876");
producer.setNamesrvAddr(namesrvAddr);
producer.setVipChannelEnabled(false);
try {
/**
* Producer对象在使用之前必须要调用start初始化,只能初始化一次
*/
producer.start();
} catch (Exception e) {
e.printStackTrace();
}
// producer.shutdown(); 一般在应用上下文,关闭的时候进行关闭,用上下文监听器 }
6.4 生产者1、Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.17.42.1:10911> failed
2、com.alibaba.rocketmq.client.exception.MQClientException: Send [1] times, still failed, cost [1647]ms, Topic: TopicTest1, BrokersSent: [broker-a, null, null]
3、org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [497]ms, Topic: TopicTest, BrokersSent: [chenyaowudeMacBook-Air.local, chenyaowudeMacBook-Air.local, chenyaowudeMacBook-Air.local]
解决:多网卡问题处理1、设置producer: producer.setVipChannelEnabled(false);
2、编辑ROCKETMQ 配置文件:broker.conf(下列ip为自己的ip)
namesrvAddr = 192.168.0.101:9876
brokerIP1 = 192.168.0.101
6.5 DESC: service not available now, maybe disk full, CL:
解决:修改启动脚本runbroker.sh,在里面增加一句话即可:JAVA_OPT="${JAVA_OPT} -Drocketmq.broker.diskSpaceWarningLevelRatio=0.98"
(磁盘保护的百分比设置成98%,只有磁盘空间使用率达到98%时才拒绝接收producer消息)
官网:SpingBoot2底层是用spring5,开始支持响应式编程,Spring又是基于Reactor试下响应式
资料:
2.1、reactive-streams学习资料:
2.2、web-flux相关资料:
webflx介绍
3.1、Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架
3.2、Flux和Mono User List
简单业务而言:和其他普通对象差别不大,复杂请求业务,就可以提升性能
通俗理解:
Mono 表示的是包含 0 或者 1 个元素的异步序列
mono->单一对象 User redis->用户ID-》唯一的用户Mono
Flux 表示的是包含 0 到 N 个元素的异步序列
flux->数组列表对象 List redis->男性用户->Flux
Flux 和 Mono 之间可以进行转换
与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞,并 通过Reactor项目实现Reactive Streams规范。RxJava
3.3、Spring WebFlux有两种风格:基于功能和基于注解的。基于注解非常接近Spring MVC模型,如以下示例所示:
第一种:
@RestController
@RequestMapping(“/ users”)
public class MyRestController {
@GetMapping(“/ {user}”)
public Mono <User> getUser( @PathVariable Long user){
// ...
}
@GetMapping(“/ {user} / customers”)
public Flux <Customer> getUserCustomers( @PathVariable Long user){
// ...
}
@DeleteMapping(“/ {user}”)
public Mono <User> deleteUser( @PathVariable Long user){
// ...
}
}
第二种: 路由配置与请求的实际处理分开
@Configuration
public class RoutingConfiguration {
@Bean
public RouterFunction <ServerResponse> monoRouterFunction(UserHandler userHandler){
return route(GET( “/ {user}”).and(accept(APPLICATION_JSON)),userHandler :: getUser)
.andRoute(GET(“/ {user} / customers”).and(accept(APPLICATION_JSON)),userHandler :: getUserCustomers)
.andRoute(DELETE(“/ {user}”).and(accept(APPLICATION_JSON)),userHandler :: deleteUser);
}
}
@Component
public class UserHandler {
公共 Mono <ServerResponse> getUser(ServerRequest请求){
// ...
}
public Mono <ServerResponse> getUserCustomers(ServerRequest request){
// ...
}
公共 Mono <ServerResponse> deleteUser(ServerRequest请求){
// ...
}
}
3.4、Spring WebFlux应用程序不严格依赖于Servlet API,因此它们不能作为war文件部署,也不能使用src/main/webapp目录
3.5、可以整合多个模板引擎
除了REST Web服务外,您还可以使用Spring WebFlux提供动态HTML内容。Spring WebFlux支持各种模板技术,包括Thymeleaf,FreeMarker
应用
4.1、WebFlux中,请求和响应不再是WebMVC中的ServletRequest和ServletResponse,而是ServerRequest和ServerResponse
4.2、加入依赖,如果同时存在spring-boot-starter-web,则会优先用spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
4.3、测试
localhost:8080/api/v1/user/test
启动方式默认是Netty,8080端口
4.4、参考:https://spring.io/blog/2016/04/19/understanding-reactive-types
webClient客户端
5.1、反应式客户端
官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-webclient
使用SSH:修改Mapping的produces属性为"text/event-stream;charset=UTF-8"
var source=new EventSource("controller");
source.onmessage=function(event)
{
document.getElementById("result").innerHTML+=event.data + "
";
//dosomething
};
source.onopen=function(event)
{
//dosomething
};
source.ononerror=function(event)
{
//dosomething
};
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
#设置actuator监控端口
management.server.port=8081
#开启所有监控,默认只开启health和info
management.endpoints.web.exposure.include=*
#添加info信息
info.author=monkey1024
info.url=www.monkey1024.com