注解 @Autowired
文档
从 Spring 2.5 开始,该框架引入了注解驱动的依赖注入 。此功能的主要注释是*@Autowired* 。 它允许 Spring 解析协作 bean 并将其注入到我们的 bean 中。
启用注解注入后,我们可以对属性、设置器和构造器使用自动装配 。
四个Bean注解对应四层,作用相同
@Component
@Repository
@Service
@Controller
核心 自动装配
@SpringBootApplication
@EnableAutoConfiguration
@Import(AutoConfigurationImportSelector.class)
public String[] selectImports()
protected AutoConfigurationEntry getAutoConfigurationEntry()
protected List getCandidateConfigurations()
protected Class<?> getSpringFactoriesLoaderFactoryClass()
public static List loadFactoryNames()
private static Map<String, List> loadSpringFactories()
public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;
xxxxAutoConfiguration…向容器种自动配置组件。由@…On…进行条件过滤
xxxxProperties 自动配置类,装配配置文件中的自定义内容
pom.xml
springboot-boot-dependencies: 核心依赖在父工程中
在引入SprinBoot依赖时,不需要指定版本,就因为有这些版本仓库
启动器(starter) 是什么 SpringBoot是在Spring的基础上简化Spring配置,内置了Tomcat Web服务器,快速整合第三方框架
配置文件 1. 配置文件强大之处: 通过配置文件,修改自动配置的默认值 @Configuration() @EnableConfigurationProperties(CodecProperties.class) @ConfigurationProperties(prefix = "spring.codec") @ConditionalOnClass()
解释:
xxxxAutoConfiguration.class提供默认配置。能通过配置文件修改的默认值,即通过某个xxxProperties.class来和配置文件绑定, 就可以使用自定义的配置。
2. yaml给实体类赋值 @ConfigurationProperties(prefix = "person")
代替
3. 加载自定义配置文件 @PropertySource(value = "classpath:xxx.properties") @Value("${name}")
Web开发 要解决的问题:
导入静态资源
首页
JSP,模板引擎Thymeleaf
装配扩展SpringMVC
增删改查
拦截器
国际化 (中英文切换)
静态资源 看源码配置:
@Override public void addResourceHandlers (ResourceHandlerRegistry registry) { if (!this .resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled" ); return ; } addResourceHandler(registry, "/webjars/**" , "classpath:/META-INF/resources/webjars/" ); addResourceHandler(registry, this .mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this .resourceProperties.getStaticLocations()); if (this .servletContext != null ) { ServletContextResource resource = new ServletContextResource (this .servletContext, SERVLET_LOCATION); registration.addResourceLocations(resource); } }); }
如果自定义了静态资源路径,则不适用默认配置。否则使用如下配置:
引入静态文件的方式:
WebJars:访问方式:localhost:8080/webjars/
resources文件夹xia :访问:localhost:8080/
private static final String [] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/" ,"classpath:/resources/" , "classpath:/static/" , "classpath:/public/" };
优先级:resources > static > public
借鉴用处:
public:js等公共资源
static:图片等静态资源
resources:用户上传的文件
首页 读源码。在静态资源页面新建index.html即可。
在templates目录下的所有页面只能通过Controller跳转
templates模板引擎 (thymeleaf) 依赖
<!--Thymeleaf--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency>
导入依赖后,必然有对应的xxxxProperties:public class ThymeleafProperties{}:
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;public static final String DEFAULT_PREFIX = "classpath:/templates/" ;public static final String DEFAULT_SUFFIX = ".html" ;
使用:
在DEFAULT_PREFIX路径下,新建一个DEFAULT_SUFFIX后缀的文件test.html。
新建controller
@Controller public class IndexController { @RequestMapping("/test") public String test () { return "test" ; } }
浏览器访问http://localhost:8080/test,发现通过controller正常访问templates下的文件。
理解 :在导入thymeleaf依赖后,在处理templates下的路径时,对相应的controller的String类型返回值自动增加前缀后缀,使得正确访问html页面。
SpringMVC ※ SpringBoot中,有非常多的xxxxConfiguration帮助我们进行扩展,要特别注意。
增删改查(CRUD 拦截器(登录拦截例子
MyMvcConfig实现WebMvcConfigurer
MyMvcConfig覆写addInterceptors(InterceptorRegistry registry)方法
registry.addInterceptor(new MyHandlerInterceptor())注册一个HandlerInterceptor来拦截和放行
MyHandlerInterceptor实现HandlerInterceptor接口,主要实现什么时候拦截,什么时候放行
例子:
MyHandlerInterceptor.class
public class MyHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object loginUser = request.getSession().getAttribute("loginUser" ); if (loginUser == null ) { request.setAttribute("msg" , "没有权限,请先登录" ); request.getRequestDispatcher("/index.html" ).forward(request, response); return false ; } return true ; } }
MyMvcConfig.(InterceptorRegistry registry)
@Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(new MyHandlerInterceptor ()) .addPathPatterns("/**" ) .excludePathPatterns("/index.html" , "/" , "/user/login" , "/css/**" , "/js/**" , "/img/**" ); }
国际化 配置I18n文件 i18n :internationalization
resource下新建i18n文件夹
i18n下新建
自定义LocaleResolver组件 注入Spring容器 数据库(Data 导入JDBC和MYSQL依赖
<dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency >
配置mysql:
spring: datasource: username: root password: root url: jdbc:mysql://192.168.31.40:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver
JdbcTemplate Spring实现的Bean,方便的进行数据操作的模板Bean。
示例:
没有实体类时获取数据
@RequestMapping("/allDatabases") public List<Map<String, Object>> allDatabases () { String sql = "show databases" ; List<Map<String, Object>> list = jdbcTemplate.queryForList(sql); return list; }
实体类获取数据
@RequestMapping("/get") public List<User> get () { String sql = "SELECT * FROM mybatis.user" ; List<User> list = jdbcTemplate.query(sql, new RowMapper <User>() { @Override public User mapRow (ResultSet rs, int rowNum) throws SQLException { return new User (rs.getInt("id" ), rs.getString("username" ), rs.getString("password" )); } }); return list; }
新增
@RequestMapping("/add") public String add () { String sql = "INSERT INTO mybatis.user('username', 'password') VALUES ('zhangsan', '123')" ; jdbcTemplate.update(sql); return "insert is ok!" ; }
修改
@RequestMapping("update/{id}") public String update (@PathVariable("id") Integer id) { String sql = "UPDATE mybatis.user SET username=?, password=? WHERE id =?" ; Object[] objects = new Object []{"lisi" , "123" , id}; jdbcTemplate.update(sql, objects); return "update is OK!" ; }
删除
@RequestMapping("/delete/{id}") public String delete (@PathVariable("id") Integer id) { String sql = "DELETE FROM mybatis.user WHERE id = ?" ; jdbcTemplate.update(sql, id); return "delete is OK!" ; }
DRUID alibaba开源平台下的一个数据库连接池
导入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.2.8</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-log4j2</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 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 spring: datasource: username: root password: root url: jdbc:mysql://192.168.31.40:3306/mybatis?useUnicode=true&characterEncoding=utf-8 type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 minIdle: 10 max-active: 20 max-wait: 60000 time-between-eviction-runs-millis: 2000 min-evictable-idle-time-millis: 600000 max-evictable-idle-time-millis: 900000 validationQuery: select 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxOpenPreparedStatements: 20 keepAlive: true aop-patterns: "com.springboot.template.dao.*" filters: stat,wall,log4j2 filter: stat: enabled: true db-type: mysql log-slow-sql: true slow-sql-millis: 2000 slf4j: enabled: true statement-log-error-enabled: true statement-create-after-log-enabled: false statement-close-after-log-enabled: false result-set-open-after-log-enabled: false result-set-close-after-log-enabled: false web-stat-filter: enabled: true url-pattern: /* exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" session-stat-enable: true session-stat-max-count: 1000 stat-view-servlet: enabled: true url-pattern: /druid/* reset-enable: false login-username: 1 login-password: 1 allow: 127.0 .0 .1 deny:
监控后台
MyBatis 一个持久层框架
导入依赖
<dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.2.2</version > </dependency >
Dao层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Mapper @Repository public interface UserDao { @Select("SELECT * FROM user") List<User> getUsers () ; @Select("SELECT * FROM user WHERE id = #{id}") User getUserById (Integer id) ; @Insert("INSERT INTO mybatis.user(username, password) VALUES ('zhangsan', '123')") boolean addUser () ; @Update("UPDATE mybatis.user SET username=#{username}, password=#{password} WHERE id = #{id}") boolean updateUser (Integer id, String username, String password) ; @Delete("DELETE FROM mybatis.user WHERE id = #{id}") boolean deleteUserById (Integer id) ; }
controller层调用:
@RequestMapping("/get") public List<User> get () { return userDao.getUsers(); }@RequestMapping("/delete/{id}") public String delete (@PathVariable("id") Integer id) { userDao.deleteUserById(id); return "delete is OK!" ; }
SpringSecurity(安全 web开发中,安全第一位。过滤器、拦截器可以实现。SpringSecurity是一个安全方面的框架
非功能性需求
漏洞、隐私泄露
Shrio\Security:很像、名字不一样,解决认证和授权问题
关键类
WebsecurityConfigurerAdapter:自定义Security安全策略
AuthenticationManagerBuilder:自定义认证策略
@EnableWebSecurity:开启WebSecurity模式,
SpringSecurity主要目标时“认证”和”授权“。
步骤 1.导入依赖 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-security</artifactId > </dependency >
2.配置类 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 @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure (HttpSecurity http) throws Exception { http.authorizeHttpRequests().antMatchers("/" ).permitAll() .antMatchers("/level1/**" ).hasRole("vip1" ) .antMatchers("/level2/**" ).hasRole("vip2" ) .antMatchers("/level3/**" ).hasRole("vip3" ); http.formLogin(); http.csrf().disable(); http.logout().logoutSuccessUrl("/" ); http.rememberMe(); } @Override protected void configure (AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .passwordEncoder(new BCryptPasswordEncoder ()) .withUser("1" ).password(new BCryptPasswordEncoder ().encode("1" )).roles("vip1" ).and() .withUser("2" ).password(new BCryptPasswordEncoder ().encode("1" )).roles("vip2" ).and() .withUser("3" ).password(new BCryptPasswordEncoder ().encode("1" )).roles("vip3" ).and() .withUser("root" ).password(new BCryptPasswordEncoder ().encode("1" )).roles("vip1" , "vip2" , "vip3" ); } }
Shrio Apache Shrio 是一个安全框架,既可以用在JavaEE、也可以用在JavaSE。可以完成认证、授权、加密、会话管理,Web集成、缓存等
分布式开发 接口文档:Swagger2 8. 任务调度 9. SprintSecurity: Shiro