自动注入
yaml方式
在类上加Component、ConfigurationProperties(perfix=yaml中的前缀)
properties方式
多环境配置 spring.profiles.active=dev
选择生效配置
application-dev.properties
、application-test.properties
静态资源 Thymeleaf 1 2 3 4 5 6 7 8 <dependency > <groupId > org.thymeleaf</groupId > <artifactId > thymeleaf-spring5</artifactId > </dependency > <dependency > <groupId > org.thymeleaf.extras</groupId > <artifactId > thymeleaf-extras-java8time</artifactId > </dependency >
1 2 3 4 5 6 7 xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro" <html lang ="en" xmlns:th ="http://www.thymeleaf.org" xmlns:sec ="http://www.thymeleaf.org/extras/spring-security" xmlns:shiro ="http://www.pollix.at/thymeleaf/shiro" >
普通文本 th:文本元素="${变量}"或者[[ ${变量} ]]
超链接 th:链接元素="@{变量}"
遍历元素 th:each="item:${items}" th:text="${item}"
国际化消息 th:文本元素="#{变量}"
``逻辑判断 th:text=”${表达式 ? 结果}”`
三元运算 th:text="${表达式?'选项1':'选项2'}"
自定义SpringMVC
在自定义类上添加@Configuration
注解
实现WebMvcConfigurer
接口
写相关的类并注入到springboot中
springboot将类注入方法
@Bean
public 要注入的类 className(){
return new 要注入的类;
}
Mybatis
在主类上添加@MapperScan("com.kuang.mapper")
在mapper接口添加@Mapper
1 2 3 4 5 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.1.3</version > </dependency >
1 2 3 4 5 6 7 <?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.kuang.mapper.UserMapper" > </mapper >
1 2 3 4 5 6 7 8 9 10 11 12 13 @Mapper @Repository public interface UserMapper { List<User> queryUserList () ; User queryUserById (Integer id) ; void addUser (User user) ; void updateUser (User user) ; void deleteUser (Integer id) ; }
1 2 3 4 5 6 7 8 9 10 11 @Controller public class UserController { @Autowired private UserMapper userMapper; @ResponseBody @RequestMapping("/user/queryAll") public List<User> queryUserList () { return userMapper.queryUserList(); } }
1 2 3 4 5 6 7 8 9 10 11 12 spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver spring.datasource.name =defaultDataSource spring.datasource.url =jdbc:mysql://localhost:3306/springbootstudy?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC spring.datasource.username =root spring.datasource.password =123456 mybatis.mapper-locations =classpath:mybatis/mapper/*.xml
SpringSecurity 1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-security</artifactId > </dependency >
授权 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure (HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/" ).permitAll() .antMatchers("/level1/**" ).hasRole("vip1" ) .antMatchers("/level2/**" ).hasRole("vip2" ) .antMatchers("/level3/**" ).hasRole("vip3" ); http.formLogin().loginPage("/toLogin" ); http.logout(). deleteCookies("remove" ).invalidateHttpSession(true ) .logoutSuccessUrl("/" ); http.rememberMe(); } }
认证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure (AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder ()) .withUser("zhangsan" ).password(new BCryptPasswordEncoder ().encode("123456" )).roles("vip1" ) .and() .withUser("lisi" ).password(new BCryptPasswordEncoder ().encode("123456" )).roles("vip1" ,"vip2" ); } }
整合Thymeleaf 1 2 3 4 5 <dependency > <groupId > org.thymeleaf.extras</groupId > <artifactId > thymeleaf-extras-springsecurity5</artifactId > <version > 3.0.4.RELEASE</version > </dependency >
1 2 <html lang ="en" xmlns:th ="http://www.thymeleaf.org" xmlns:sec ="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5" > </html >
Shiro 快速开始 Apache Shiro Tutorial | Apache Shiro
pom.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.0</version > <configuration > <source > 1.8</source > <target > 1.8</target > </configuration > </plugin > <plugin > <groupId > org.codehaus.mojo</groupId > <artifactId > exec-maven-plugin</artifactId > <version > 1.1</version > <executions > <execution > <goals > <goal > java</goal > </goals > </execution > </executions > <configuration > <classpathScope > test</classpathScope > <mainClass > Tutorial</mainClass > </configuration > </plugin > </plugins > </build > <dependencies > <dependency > <groupId > commons-logging</groupId > <artifactId > commons-logging</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > org.apache.shiro</groupId > <artifactId > shiro-core</artifactId > <version > 1.9.0</version > </dependency > <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-simple</artifactId > <version > 1.7.21</version > </dependency > <dependency > <groupId > org.slf4j</groupId > <artifactId > jcl-over-slf4j</artifactId > <version > 1.7.21</version > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.14</version > </dependency > </dependencies >
log4j2.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <Configuration name="ConfigTest" status="ERROR" monitorInterval="5"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Logger name="org.springframework" level="warn" additivity="false"> <AppenderRef ref="Console"/> </Logger> <Logger name="org.apache" level="warn" additivity="false"> <AppenderRef ref="Console"/> </Logger> <Logger name="net.sf.ehcache" level="warn" additivity="false"> <AppenderRef ref="Console"/> </Logger> <Logger name="org.apache.shiro.util.ThreadContext" level="warn" additivity="false"> <AppenderRef ref="Console"/> </Logger> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
shiro.ini 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [users] root = secret, adminguest = guest, guestpresidentskroob = 12345 , presidentdarkhelmet = ludicrousspeed, darklord, schwartzlonestarr = vespa, goodguy, schwartz[roles] admin = *schwartz = lightsaber:*goodguy = winnebago:drive:eagle5
Toturial 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.session.Session;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main (String[] args) { log.info("My First Apache Shiro Application" ); Factory<SecurityManager> factory = new IniSecurityManagerFactory ("classpath:shiro.ini" ); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject currentUser = SecurityUtils.getSubject(); Session session = currentUser.getSession(); session.setAttribute("someKey" , "aValue" ); String value = (String) session.getAttribute("someKey" ); if (value.equals("aValue" )) { log.info("Retrieved the correct value! [" + value + "]" ); } if (!currentUser.isAuthenticated()) { UsernamePasswordToken token = new UsernamePasswordToken ("lonestarr" , "vespa" ); token.setRememberMe(true ); try { currentUser.login(token); } catch (UnknownAccountException uae) { log.info("There is no user with username of " + token.getPrincipal()); } catch (IncorrectCredentialsException ice) { log.info("Password for account " + token.getPrincipal() + " was incorrect!" ); } catch (LockedAccountException lae) { log.info("The account for username " + token.getPrincipal() + " is locked. " + "Please contact your administrator to unlock it." ); } catch (AuthenticationException ae) { } } log.info("User [" + currentUser.getPrincipal() + "] logged in successfully." ); if (currentUser.hasRole("schwartz" )) { log.info("May the Schwartz be with you!" ); } else { log.info("Hello, mere mortal." ); } if (currentUser.isPermitted("lightsaber:wield" )) { log.info("You may use a lightsaber ring. Use it wisely." ); } else { log.info("Sorry, lightsaber rings are for schwartz masters only." ); } if (currentUser.isPermitted("winnebago:drive:eagle5" )) { log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " + "Here are the keys - have fun!" ); } else { log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!" ); } currentUser.logout(); System.exit(0 ); } }
Springboot 导入依赖 1 2 3 4 5 <dependency > <groupId > org.apache.shiro</groupId > <artifactId > shiro-spring</artifactId > <version > 1.9.0</version > </dependency >
shiro配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.kuang.config;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.Map;@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean (@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean (); factoryBean.setSecurityManager(securityManager); Map<String, String> filterMap = new LinkedHashMap <>(); filterMap.put("/user/*" ,"authc" ); factoryBean.setFilterChainDefinitionMap(filterMap); factoryBean.setLoginUrl("/toLogin" ); return factoryBean; } @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager (@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager (); securityManager.setRealm(userRealm); return securityManager; } @Bean(name="userRealm") public UserRealm userRealm () { return new UserRealm (); } }
认证授权 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.kuang.config;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;public class UserRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { return null ; } @Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException { String name = "root" ; String password = "123456" ; UsernamePasswordToken userToken = (UsernamePasswordToken)authenticationToken; if (!userToken.getUsername().equals(name)){ return null ; } return new SimpleAuthenticationInfo ("" ,password,"" ); } }
mybatis 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.kuang.config;import com.kuang.pojo.User;import com.kuang.service.UserServiceImpl;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;public class UserRealm extends AuthorizingRealm { UserServiceImpl userService; @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo (); Subject subject = SecurityUtils.getSubject(); User currentUser = (User) subject.getPrincipal(); return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken userToken = (UsernamePasswordToken)authenticationToken; User user = userService.queryUserByName("userToken.getUsername()" ); if (user==null ){ return null ; } return new SimpleAuthenticationInfo (user,user.getPassword(),"" ); } }
Thymeleaf 1 2 3 4 5 6 7 <dependency > <groupId > com.github.theborakompanioni</groupId > <artifactId > thymeleaf-extras-shiro</artifactId > <version > 2.1.0</version > </dependency >
1 2 <html lang ="en" xmlns:th ="http://www.thymeleaf.org" xmlns:shiro ="http://www.pollix.at/thymeleaf/shiro" >
Swagger 依赖 1 2 3 4 5 6 7 8 9 10 11 12 <dependency > <groupId > io.springfox</groupId > <artifactId > springfox-swagger-ui</artifactId > <version > 3.0.0</version > </dependency > <dependency > <groupId > io.springfox</groupId > <artifactId > springfox-swagger2</artifactId > <version > 3.0.0</version > </dependency >
配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()); } private ApiInfo apiInfo(){ return new ApiInfo( "Kuang Swagger Api", "有朝一日,成为一个高手", "1.0", "https://zuoyenuandong.github.io/", new Contact("kuang", "https://zuoyenuandong.github.io/", "1400584782@qq.com"), "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList()); } }
访问链接 http://localhost:8080/swagger-ui.html
注释
ApiModel(""):在实体类上面添加注释
ApiModelProperty(""):在实体类字段添加注释
ApiOperation(""):方法添加注释
ApiParam(""):方法参数添加注释
任务 异步任务
主类上添加@EnableAsync
方法上添加@Async
邮件任务 1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-mail</artifactId > </dependency >
)
1 2 3 4 5 spring.mail.username =1400584782@qq.com spring.mail.password =pyprtzvykygyfffd spring.mail.host =smtp.qq.com spring.mail.properties.mail.smtp.ssl.enable =true
简单邮件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @SpringBootTest class SpringbootStudy08JobApplicationTests { @Autowired JavaMailSenderImpl javaMailSender; @Test void contextLoads () { SimpleMailMessage simpleMailMessage = new SimpleMailMessage (); simpleMailMessage.setSubject("springboot mail service" ); simpleMailMessage.setText("hello world" ); simpleMailMessage.setTo("2597972416@qq.com" ); simpleMailMessage.setFrom("1400584782@qq.com" ); javaMailSender.send(simpleMailMessage); } }
复杂邮件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Test void contextLoads2 () throws MessagingException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper (mimeMessage); messageHelper.setSubject("springboot mail service" ); messageHelper.setText("<p style='color:blue'>hello world</p>" ,true ); messageHelper.setTo("2597972416@qq.com" ); messageHelper.setFrom("1400584782@qq.com" ); javaMailSender.send(mimeMessage); }
定时任务 TaskScheduler:任务调度者
TaskExecutor:任务执行者
EnableScheduling:开启定时任务
Scheduled:什么时候执行
1 2 3 4 5 6 7 8 @Service public class ScheduledService { @Scheduled(cron = "0 * * * * 0-7") public void hello () { System.out.println("hello world" ); } }
Dobbo Zookeeper 准备
下载zookeeper
和dubbo-admin
将dubbo-admin
打包成一个jar包mvn clean package -Dmaven.test.skip=true
dubbo-admin
的端口号为7001
zookeeper
的端口号为2181
,默认用户名和密码都是root
springboot 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <dependency > <groupId > org.apache.dubbo</groupId > <artifactId > dubbo-spring-boot-starter</artifactId > <version > 2.7.8</version > </dependency > <dependency > <groupId > com.github.sgroschupf</groupId > <artifactId > zkclient</artifactId > <version > 0.1</version > </dependency > <dependency > <groupId > org.apache.curator</groupId > <artifactId > curator-framework</artifactId > <version > 2.12.0</version > </dependency > <dependency > <groupId > org.apache.curator</groupId > <artifactId > curator-recipes</artifactId > <version > 2.12.0</version > </dependency > <dependency > <groupId > org.apache.zookeeper</groupId > <artifactId > zookeeper</artifactId > <version > 3.4.8</version > <exclusions > <exclusion > <groupId > org.slf4j</groupId > <artifactId > slf4j-log4j12</artifactId > </exclusion > </exclusions > </dependency >