Spring的核心是提供一个容器(container),又叫spring Application Context,会创建和管理bean,将bean装配在一起基于依赖注入(DI),依赖容器去创建和维护所有的组件,注入需要的bean中。
bean的注入方式:
Maven项目结构
项目源码 src/main/java
测试源码 src/test/java
非Java资源 src/main/resources
pom.xml maven构建规范;
Application.java SpringBoot主类,项目启动;
application.properties 指定配置属性
SpringBoot
@SpringBootApplication
包含
@SpringBootConfiguration
声明配置类,@Configuration的特殊形式;@EnableAutoConfiguration
启用自动配置;@ComponentScan
组件扫描,通过@Component @Controller @Service声明其他类,自动发现并注册组件Spring自带一个Web框架,SpringMVC,核心是控制器,处理请求并以某种方式进行信息响应,填充数据模型并将请求传递给视图。@Controller @GetMapping 发送HTTP GET请求; @RequestMapping 类级别使用,通用的请求处理;
thymeleaf模版
添加依赖
org.springframework.boot
spring-boot-starter-thymeleaf
标签属性:
th:text
命名空间中的属性
th:each="XXX : ${} "
迭代元素集合
th:value
渲染设置value属性
th:src="@{/ }
" 图片地址
引用样式
提交url
th:if
条件语句
测试类
JUnit
@RunWith(SpringRunner.class)
测试运行器 @SpringBootTest
;
@WebMvcTest(XXController.class)
是SpringBoot提供的特殊测试注解,将某某注册到SpringMVC中;
注入MockMvc,实现mockup;mockMVC.perform(get("/"))
发起对“/”的请求
.andExpect()
期望…;
SpringMVC
@Data
添加Lombok依赖,节省空间,并且运行时动态生成方法;@RequestMapping("/") @GetMapping("/")
要么将请求传递给视图渲染HTML,要么将数据写入响应体(RESTful);@Slf4j
,会自动生成一个SLF4J Logger。
org.springframework.boot
spring-boot-starter-thymeleaf
@PostMapping
@NotNull
非空 @Size
长度 @CreditCardNumber
合法的信用卡号 @Pattern
正则表达式@DIgits(integer=)
包含几位数字hasErrors()
会检验是否有错误,th:errors="*{ }"
DevTools 好处
代码变更后应用会自动重启;
当面向浏览器的资源发生变化时,会自动刷新浏览器;
自动禁用模版缓存;
当DevTools运行时,应用程序会被加载到Java虚拟机两个独立的类加载器中,一个类加载器会加载代码,属性文件等,另一个加载依赖的库,当有变更时,只会重新加载包含项目代码的类加载器;
处理关系型数据时,使用Spring的JDBC和JPA;
JDBC
添加依赖
org.springframework.boot
spring-boot-starter-jdbc
查询
jdbcTemplate.queryForObject()
返回一个对象
jdbcTemplate.query()
返回对象的集合h d s y y
插入
jdbcTemplate.update()
@SessionAttribute("")
指定对象保存在session中,跨请求使用
@modelAttribute(name ="")
在模型中创建对象
Spring Data JPA
SpringData
添加依赖
org.springframework.boot
spring-boot-starter-data-jpa
@Entity
声明实体
@Id
唯一标识属性
@GeneratedValue(strategy = GenerationType.AUTO)
依赖数据库自动生成ID值
@NoArgsConstructor
无参构造器
@RequiredArgsConstructor
有参构造器
@PrePersist
在持久化前做…
@ManyToMany
表之间属性多对多关系
@Table(name = "")
持久化到某个表中
声明JPA的repository
扩展CrudRepository<持久化的实体类型,实体ID属性的类型>
运行时会自动生成实现类,SpringData解析方法名来确定要执行的查询
添加依赖
org.springframework.boot
spring-boot-starter-security
配置SpringSecurity
应用启动时,添加依赖后,自动配置功能会探测,初始化基本的安全配置;
通过覆盖WebSecurityConfigurerAdapter
基础配置类中定义的configure()
方法来进行配置;
SpringSecurity为配置用户存储提供多个方案
基于内存的用户存储
AuthenticationManagerBuilder.inMemoryAuthentication()
指定信息,调用withUser()
配置一个用户(用户名),密码和授权信息通过password()
,authorities()
方法来指定;
基于JDBC的用户存储
用户信息一般在数据库维护,调用AuthenticationManagerBuilder.jdbcAuthentication().datasource()
;
查找用户信息,可以自定义查询, 调用Auth...usersByUsernameQuery()
;
密码存储需要使用转码后的密码,通过Auth...passwordEncoder()
指定一个encoder密码转码器
例如StandardPasswordEncode SHA-256哈希加密
以LDAP作为后端的用户存储
用AuthenticationManagerBuilder.ldapAuthentication().userSearchFilter().groupSearchFilter()
基础查询提供条件;
引用远程的LDAP服务器Auth...contextSource().url("指定服务器地址")
配置嵌入式的LDAP服务器 Auth...contextSource().root
指定嵌入式服务器的前缀;
*自定义用户认证
创建领域类实现SpringSecurity的UserDetails接口,会得到getAuthorities()
等方法;
定义repository接口extends CrudRepository<,>
,定义一个findByUserName()
方法;
创建用户详情服务接口,实现SpringSecurity的UserDetailsService接口,返回UserDetails对象;
回到configure方法中,注入userDetailsService,调用Auth.userDetailsService()
,调用passwordEncoder()
进行密码转码,查询用户信息;
保护Web请求
配置HttpSecurity常见的需求是拦截请求以确保用户具备适当的权限,
httpSecurity.authorizeRequests()
.antMatchers("/")
.hasRole("")
登录
.and()
.formLogin()
.loginPage("/")
退出
.and()
.logout()
.logoutSuccessUrl("/")
防止跨站请求伪造
SpringSecurity 提供了内置的CSRF(跨站请求伪造)保护,如果使用SpringMVC的jsp标签库或者thyme leaf方言,会自动生成包含CSRF token的隐藏域;
已认证用户的信息可以通过SecurityContext对象来获取,也可以用@AuthenticationPrincipal
注入控制器中;
Spring中有两种配置
环境抽象 application.yaml文件中
端口号
server:
port: XXX
配置数据源
spring:
datasource:
url:
username:
password:
配置嵌入式服务器
任选一个可用的端口
server:
port: 0
常见的对底层容器的设置就是处理HTTPS请求
JDK keytool命令生成keystore
$ keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA
配置日志
SpringBoot 通过Logback配置日志,INFO级别写入;
logging:
file: /
level:
root: WARN
org.springframwork.security:DEBUG
创建自己的配置属性
@ConfigurationProperties(prefix=“XX.XX”)
XX:
XX:
属性值:XX
使用profile进行配置
application-{profile名}.yml
激活profile 使用环境变量来设置处于激活状态的profile;
% export SPRING_PROFILES_ACTIVE =prod,xx,xx
创建RESTful控制器
@RestController
能够让类被组件扫描功能发现,并且控制器中的所有处理器方法的返回值都要直接写入响应体中;
@Controller@ResponseBody
这样返回的就是ResponseEntity对象;
@RequestMapping(path="/",produces={“application/json”,""})
代表只会处理Accept头信息包含"application/json"的请求,限制API只生成JSON结果。
@CrossOrigin(origins="*")
允许来自任何域的客户端消费该API
@PathVariable(“XX”) @GetMapping("/{/XX}") 对应
返回值设为ResponseEntity,有返回值则ok的HTTP状态,否则为NOT FOUND的状态;
发送数据到服务器端
在服务器上更新数据
删除服务器上的数据
启用数据后端服务
添加依赖
org.springframework.boot
spring-boot-starter-data-rest
它会为Spring Data创建的repository自动生成REST API;
@RestResource(rel="",path="") 能为实体提供任何我们想要的关系名和路径;
分页与排序
http://localhost:8080/xx/xx/xx?sort=creatAt,desc&page=X&size=X
JMS发送消息
使用消息代理的通用API,基于JmsTemplate,消息生产方发送队列和主题消息,提供消息驱动POJO;
搭建环境,使用ActiveMQ;
添加依赖
org.springframework.boot
spring-boot-starter-activemq
配置属性
spring:
activemq:
broker-url: 代理的url
user: 访问代理的用户
password: 密码
in-memory: 是否在内存中运行代理,默认为true
send(),都需要MessageCreator来生成Message对象;
converAndSend()接受Object对象,自动转换为Message对象;
配置消息转换器 MessageConverter 有两个方法, ToMessage(),fromMessage()
接收JMS消息
receive() ;接收XX队列的消息;
receiveAndConvert() 不需要MessageConverter注入进来,转换操作在方法幕后进行;
声明消息监听器
@JmsListener(“xx.xx.quene”)
这个注解会等待消息抵达指定的目的地,当消息到达时,方法被自动被调用;优点是不会堵塞,快速处理多个消息;缺点是只能用在Java应用中;
RabbitMQ是AMQP最杰出的实现。JMS消息使用目的地来寻址,接收者要从这里检索消息;AMQP消息使用Exchange和routing key 来寻址,消息就与接收者要监听的对列解耦了;
当消息到RabbitMQ代理的时候,它会进入设置的Exchange上,由它负责路由到一个或多个队列中,过程会根据Exchange的类型,Exchange和队列之间的blinding,消息的routing key 进行路由;
添加依赖
org.springframework.boot
spring-boot-starter-amqp
配置属性
spring:
rabbitmq:
host:
port:
username:
password:
RabbitTemplate发送消息和接收消息基本同JMS;
@RabbitListener("")消息监听器
为集群运行设计,可扩展性很强,仅使用主题实现消息的发布/订阅;