自动装配原理
- SpringBoot启动会加载大量的自动配置类xxxAutoConfiguration
- xxxAutoConfiguration会使用@EnableConfigurationProperties注解绑定配置文件中的属性值
- 给容器中的自动配置类添加组件时,会从xxxProperties类中获取指定的属性值,只需要在配置文件中指定这些属性即可.
- 配置文件中的key和xxxProperties中@ConfigurationProperties注解的prefix属性值一一对应
pom.xml
- spring-boot-dependencies :核心依赖在父工程中
启动器starter :Springboot的启动场景
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.7.RELEASE</version> </dependency>
-
比如spring-boot-starter-web,会自动导入web环境所有的依赖
-
springboot会将所有的功能场景,都变成一个个的启动器
-
要使用什么功能,就找到对应的启动器 starter
springboot的配置文件 application.yaml
通过查看原码(ResourceProperties类)
静态资源默认访问地址
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
连接数据库,配置数据源
pom.xml引入相关依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
application.yaml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
测试
@SpringBootTest
class SpringbootTestApplicationTests {
@Autowired
DataSource dataSource;
@Test
void contextLoads() throws SQLException {
System.out.println(dataSource.getClass());
System.out.println(dataSource.getConnection());
}
}
整合mybatis
pom.xml引入相关依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
application.yaml
mybatis:
type-aliases-package: com.hyj.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
Dao层使用Mapper注解,并DI注入到容器
@Mapper
@Repository
public interface UserMapper {
public User queryById(@Param("id") int id);
}
Service层调用Dao层,并DI注入到容器
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
@Override
public User queryById(int id) {
return userMapper.queryById(id);
}
}
mapper-locations:的文件夹下创建相对应xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyj.mapper.UserMapper">
<select id="queryById" parameterType="int" resultType="user">
select * from mybatis.user where id = #{id};
</select>
</mapper>
测试
@SpringBootTest
class SpringbootTestApplicationTests {
@Autowired
private UserService userService;
@Test
void contextLoads() {
System.out.println(userService.queryById(1));
}
}
Druid 监控
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource() {
return new DruidDataSource();
}
//后台监控: web.xml
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
HashMap<String, String> initParameters = new HashMap<>();
//增加配置
initParameters.put("loginUsername","admin"); //登录key 固定 loginUsername loginPassword
initParameters.put("loginPassword","123456");
//允许谁可以访问
//initParameters.put("allow","127.0.0.2");
//禁止谁访问 禁止ip访问
// initParameters.put("deny","127.0.0.1");
bean.setInitParameters(initParameters);
return bean;
}
//filter
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
HashMap<String, String> initParameters = new HashMap<>();
//这些东西不进行统计
initParameters.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParameters);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
配置完成后访问工程路径/druid,通过设置好的账号密码登录后台监控页面
自定义WebMvcConfigurer
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
public static class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
//自定义视图解析器
@Bean
public ViewResolver MyViewResolver(){
return new MyViewResolver();
}
//自定义国际化相关
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/css/**","/img/**");
}
}
国际化
自定义LocaleResolver类
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
String lang = httpServletRequest.getParameter("lang");
Locale aDefault = Locale.getDefault();
if(lang!=null && !("".equals(lang))) {
String[] s = lang.split("_");
aDefault = new Locale(s[0],s[1]);
}
return aDefault;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
html层中英文切换传参
<a th:href="@{/login(lang='zh_CN')}">中文</a>
<a th:href="@{/login(lang='en_US')}">英文</a>
添加到自定义的WebMvcConfigurer
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
return new MyLocaleResolver();
}
}
自定义Spring Security(登录、注销、授权、认证功能)
自定义类SecurityConfig继承WebSecurityConfigurerAdapter类
链式编程
package com.hyj.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//antMatchers表示请求,hasRole表示拥有权限才能访问
//permitAll() 允许所有人访问
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//formLogin() 开启登录功能
//loginPage() 自定义登录页面请求 默认/login
//loginProcessingUrl() 处理登录的请求,和loginPage页面的from表单的登录请求一致
//usernameParameter() 和loginPage页面的from表单的用户名的name属性一致 默认为username
//passwordParameter() 和loginPage页面的from表单的密码的name属性一致 默认为password
//rememberMe() 和loginPage页面的from表单的记住我选择框的name属性一致
/*
源码:
http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin()
* .usernameParameter("username") // default is username
* .passwordParameter("password") // default is password
* .loginPage("/authentication/login") // default is /login with an HTTP get
* .failureUrl("/authentication/login?failed") // default is /login?error
* .loginProcessingUrl("/authentication/login/process"); // default is /login
*/
http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login").usernameParameter("username").passwordParameter("password");
//logout() 功能出现404就增加此行代码
http.csrf().disable();
http.logout().logoutSuccessUrl("/");
http.rememberMe();
}
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//手动加用户,可以从数据库读取用户账号、密码、权限
//passwordEncoder() 密码加密
//withUser() 用户名
//password() 密码
//roles() 权限
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("heyanjie").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and()
.withUser("zjw").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2");
}
}
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" type="text/css" th:href="@{/css/login-css.css}"/>
</head>
<body>
<div id="login">
<h1>Login</h1>
<!--action参数和loginProcessingUrl()的参数一致-->
<form th:action="@{/login}" method="post">
<input id="username" type="text" required="required" th:placeholder="#{login.username}" name="username"/>
<input id="password" type="password" required="required" th:placeholder="#{login.password}" name="password"/>
<button id="loginBut" class="but" type="submit">登录</button>
</form>
</div>
</body>
</html>
controller
package com.hyj.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RouterController {
//自定义的登录页面请求,和loginPage()的参数一致
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
}