目录
SpringBoot
Spring IOC
- IOC基本功能:
- 每个需要管理的对象称为Bean,管理Bean的容器称为IOC容器
- 通过描述管理Bean,包括发布和获取Bean
- 通过描述完成Bean之间的依赖关系
- IOC容器:
- 所有IOC容器需要实现接口BeanFactory
- 接口中允许按类型或名称获取Bean实例 --- getBean
- isSingleton判断Bean是否单例,相反isPrototype判断Bean是否为原型
- SpringBoot中通过注解装配Bean到SpringIOC容器
- 配置文件注解:
- @Configuration代表是Java配置文件,Spring容器会根据它装配Bean
- @Bean代表将方法返回的对象装配到IOC容器中
- Spring可以通过xml和java配置文件来装配Bean
- 装配Bean:
- 扫描装配Bean:
- @Component --- 标明哪个类被扫描进入SpringIOC容器
- @ComponentScan --- 标明采用何种策略去扫描装配Bean
- 依赖注入:
- @Autowired --- 根据属性的类型找到对应的Bean进行注入
- 首先根据类型找到对应的Bean,如果对应类型的Bean不是唯一的,会根据属性名称和Bean的名称进行匹配
- 消除歧义性:避免IOC根据Bean的名称去匹配
- @Primary --- 设定优先权
- @Qualifier("dog") --- 设定匹配实例
- 带参构造方法的依赖注入:
public Person(@Autowired Animal animal)
- 生命周期:
- Bean定义:
- 1.通过@ComponentScan定义的扫描路径找到带有@Component的类 --- 资源定位
- 2.解析资源,保存定义信息
- 3.将Bean定义发布到IOC容器中
- Bean初始化:
- Bean的生存期和销毁
- 属性文件:
- application.properties/application.yml
- @Value("${database.url}") --- 通过注解读取配置文件
- @Configuration("database") --- 通过属性名自动匹配读取
- @PropertySource(value={"classpath:jdbc.properties"},ignoreResourceNotFound=true)
- 条件装配:
- @Conditional(DatabaseConditional.class)
- 需要实现Condition的matches方法
- Bean的作用域:
- @Scope(ConfigurableBeanFacory.SCOPE_PROTOTYPE)
- singleton --- 单例
- prototype --- 原型
- session --- http会话
- application --- web工程生命周期
- request --- web工程单次请求
- 部署环境切换:
- @Profile4("dev")
- 切换application-dev.properties配置文件
- 使用XML配置Bean:
- 在配置类@Configuration中载入XML
- @ImportResource(value = {"classpath:spring.xml"})
Spring AOP
- AOP约定编程:Spring AOP通过约定,把对应的方法通过动态代理技术(Proxy)织入约定的流程中
- AOP概念:@AspectJ
- 连接点:具体被拦截的对象(特定的方法) --- 把某一方法织入对应的流程中
- 切点:通过正则式和指示器适配连接点,拦截多个类的不同方法
- 通知:流程下的方法,分为前置通知、后置通知、环绕通知、事后返回通知、异常通知
- 目标对象:被代理对象target
- 引入:引入新的类和其方法,增强现有Bean的功能
- 织入:动态代理,为原有服务对象生成代理对象
- 切面:一个可以定义切点、各类通知和引入的内容
- AOP开发:
- 确定连接点:确定哪个方法需要AOP
- 开发切面:@Aspect切面声明
- 通过注解定义通知:@Before,@After,@AfterReturning,@AfterThrowing等
@Aspect
public class MyAspect {
@Before("execution(*
com.xxx.UserService.printUser(..))")
public void before() {
System.out.println("before ......");
}
}
@Pointcut("execution(*com.xxx.UserService.printUser(..))")
public void pointcut() {}
@Before("pointfcut()")
public void before() {......}
- 正则式:
"execution(*com.xxx.UserService.printUser(..))"
- execution : 执行时拦截内部的正则匹配的方法
* : 表示任意返回类型
- com.xxx.UserService : 目标对象的全限定名
- printUser : 指定目标对象的方法
- (..) : 表示任意参数进行匹配
- 环绕通知:
- 取代/回调原有目标对象方法
- 一般用于需要大幅度修改原有目标对象的服务逻辑
- 引入:增强被拦截的接口的功能
- @DeclareParents --- 引入新的类增强服务
Spring 数据源
- Mybatis:
- 在配置文件中配置内容:
- properties
- settings - 设置:配置映射规则
- typeAliases - 类型别名
@Alias("xxx")
- typeHandlers - 类型处理器
- objectFactory - 对象工厂
- plugins - 插件
- environments - 数据库环境
- databaseIdProvider - 数据库厂商标识
- mappers - 映射器 :提供SQL和Java对象的映射关系
- Spring+MyBatis:
- 整合:
- MapperFactoryBean/MapperScannerConfigurer
- MapperScan -- 通过扫描加载MyBatis的Mapper(通过注解@Repository或@Mapper)
- 使用:
- 创建与表映射的对象,使用@Alias指定别名
- 使用@Repository制定Mybatis接口文件(指示为DAO层接口)
- 创建用户映射文件,指定接口文件中的方法的具体实现
- 使用@Service指定用户服务接口和其实现类
- 使用控制器@Controller来执行
- 在application.properties文件中配置MyBatis框架
- 配置SpringBoot运行文件
- 事务:
- 声明式事物@Transactional:代表该类所有公共非静态方法启用事务
- 事务管理器:DataSourceTransactionManager类
- 可设定事务的隔离等级 --- @Transactional(isolation = Isolation.SERIALIZABLE)u
- 事务传播:使用其它事务处理子方法(子@Service)
- propagation = Propagation.REQUIRED
- REQUIRED/SUPPORTS/MANDATORY/REQUIRES_NEW/NOT_SUPPORTED/NEVER/NESTED
- REQUIRED --- 子方法沿用当前事务
- REQUIRES_NEW --- 子方法使用新事务
- NESTED --- 只进行失败的子事务回滚
- Spring+MongoDB:
- MongoDB文档:@Document
- 主键字段:@id
- 属性字段:@Field
- 使用:
- 添加依赖后,Spring自动创建MongoTemplate的Bean
- 在@Service中实现服务
- 利用准则Criteria构建条件
- 构建查询(Query)等条件
- 查询:Query queryId = Query.query(criteriaId)
- 添加:mongoTmpl.save(user,"user")
- 删除:DeleteResult result = mongoTmpl.remove(queryId,User.class)
- 更新:通过Query确定需更新的对象 -> 定义更新对象Update -> 使用mongoTmpl执行更新
Spring MVC
- MVC框架:
- 控制器 -> 业务层/缓存 -> 数据访问层DAO/关系数据库
- 流程:
- 1.发送请求(Http等)
- 2.由注解@RequestMapping提供URI和其它配置
- 3.返回包含控制器逻辑的处理器(对控制器的包装)
- 4.运行处理器
- 5.ModelAndView捆绑数据模型和视图
- 6.定位视图
- 7.将用户模型渲染到视图显示
- Spring MVC的自定义配置:
- WebMvcAutoConfigurationAdapter配置类
- 控制器:
- 控制器类:@Controller,@RequestMapping("/my")
- 方法:@GetMapping/@PostMapping,@ResponseBody
- 无注解参数:方法的参数名称和HTTP请求参数名称一致
- @RequestParam规定HTTP参数和方法参数的映射关系
- 方法参数添加注解@RequestBody可以接收前端提交的请求体(JSON等)
- 通过URL传递参数 --- 注解:@GetMapping("/{id}"), 方法参数:@PathVariable("id")
- 格式化方法参数:
- 日期格式化:@DateTimeFormat(iso=ISO.DATE) Date date
- 数字格式化:@NumberFormat(pattern="#,###.##") Double number
- 通过配置进行日期格式化:spring.mvc.date-format=yyyy-MM-dd
- 自定义参数转换:
- 接口类型:Converter\Formatter\GenericConverter
- 一对一转换器:@Component实现自定义Converter接口的方法
- 集合和数组转换:GenericConverter
- 数据验证:
- 默认验证:JSR-303
- 非空判断:@NotNull(message = "xxx")
- 日期限制:@Future(message = "xxx") @Past
- 最小值:@DecimalMin(value="0.1"),@Min(value=1,message="xxx")
- 最大值:@DecimalMax(value="1000.1"),@Max(value=100,message="xxx")
- 限定范围:@Range(min=1,max=88,message="xxx")
- 邮箱格式验证:@Email(message="xxx")
- 字符串长度限制:@Size(min=20,max=30,message="xxx")
- 自定义验证器:继承Validator接口,@InitBinder绑定验证器
- 文件上传:
- MultipartHttpServletRequest
- MultipartFile
- Part
- 拦截器:
- 所有的拦截器实现HandlerInterceptor接口
- preHandle
- 处理器
- postHandle
- 视图
- afterCompletion
- 注册拦截器:在SpringBoot配置启动类中注册
- public void addInterceptors(InterceptorRegistry registry)
- 注册拦截器到SpringMVC,返回一个拦截器注册
- InterceptorRegistration ir = registry.addInterceptor(new Interceptor1())
- 指定拦截匹配模式,限制拦截器拦截请求(括号内的正则式)
- ir.addPathPatterns("/interceptor/*");
- 拦截器执行顺序
- 处理器前方法:先注册先执行
- 处理器后方法:先注册后执行
- 国际化:
- 消息源:MessageSource接口体系 --- ResourceBundleMessageSource国际化消息源
- 解析器:LocaleResolver接口
- 会话对象:
- @SessionAttribute:将HttpSession中的属性读出
- @SessionAttributes:类注解,将相关数据模型的属性保存到Session
- 控制器通知:
- @ControllerAdvice:定义一个控制器通知类
- @InitBinder:定义控制器参数绑定规则
- @ExceptionHandler:定义控制器发生异常后的操作
- @ModelAttribute:在控制器方法执行之前,对数据模型进行操作
- 获取Http请求头:
- 在控制器的方法参数中添加@RequestHeader("xxx")
- 在请求头中获取键为xxx的参数
REST
- REST风格特点:
- 服务器存在一系列资源,每个资源通过单独唯一的URI进行标识
- 客户端和服务器之间可以相互传递资源,而资源以某种表现层得以展示
- 客户端通过HTTP协议所定义的动作对资源进行操作,实现资源的状态转换
- REST风格:
#获取用户信息,1是用户编号
GET /user/1
#查询多个用户信息
GET /users/{userName}/{note}
#创建用户
POST /user/{userName}/{sex}/{note}
#修改用户全部属性
PUT /user/{id}/{userName}/{sex}/{note}
Spring Security
- 启用Spring Security:
- @EnableWebSecurity
- 自定义安全拦截方案:抽象类WebSecurityConfigurerAdapter
- configure(AuthenticationManagerBuilder) --- 配置用户签名服务指定用户角色
- configure(WebSecurity) --- 配置Filter链
- configure(HttpSecurity) --- 指定用户角色的访问权限
- 签名服务:
- 使用内存签名服务 --- BCryptPasswordEncoder
- 数据库用户认证服务 --- JdbcUserDetailsManagerConfigurer
- 自定义用户认证服务 --- UserDetailsService
- 限制请求:
- 指定用户的访问权限
- http.authorizeRequests()
- 强制使用HTTPS:
- http.requiresChannel().antMatchers("/admin/**").requiresSecure()
- 防止跨站点请求伪造:
日志
SLF4J
- SLF4J仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案
- SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,而是通过Facade Pattern提供一些Java logging API,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。
LOG4J
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Log4jTest.class)
- LOG4J有7种不同的log级别,按照等级从低到高依次为:TRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFF。如果配置为OFF级别,表示关闭log
- LOG4J支持两种格式的配置文件:properties和xml。包含三个主要的组件:Logger、appender、Layout
- 设定root日志的输出级别为INFO,appender为控制台输出stdout
# LOG4J配置
log4j.rootLogger=INFO,stdout
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
- root日志输出到logs/springboot.log文件中
# LOG4J配置
log4j.rootLogger=INFO,stdout,file
# 日志输出到文件
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.file=logs/springboot.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
- 按不同package进行输出。通过定义输出到logs/my.log的appender,并对com.test包下的日志级别设定为DEBUG级别、appender设置为输出到logs/my.log的名为testlog的appender。
# com.test包下的日志配置
log4j.logger.com.test=DEBUG, testlog
# com.test下的日志输出
log4j.appender.testlog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.testlog.file=logs/my.log
log4j.appender.testlog.DatePattern='.'yyyy-MM-dd
log4j.appender.testlog.layout=org.apache.log4j.PatternLayout
log4j.appender.testlog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n
- 对不同级别进行分类,比如对ERROR级别输出到特定的日志文件中
# LOG4J配置
log4j.rootCategory=INFO, stdout,errorfile
log4j.logger.error=errorfile
# error日志输出
log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorfile.file=logs/error.log
log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd
log4j.appender.errorfile.Threshold = ERROR
log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n %5p %c{1}:%L - %m%n
- 将日志文件输出到数据库配置
# LOG4J配置
log4j.rootCategory=INFO,stdout,jdbc
# 数据库输出
log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.jdbc.driver=com.mysql.jdbc.Driver
log4j.appender.jdbc.URL=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true
log4j.appender.jdbc.user=root
log4j.appender.jdbc.password=root
log4j.appender.jdbc.sql=insert into log_icecoldmonitor(level,category,thread,time,location,note) values('%p','%c','%t','%d{yyyy-MM-dd HH:mm:ss:SSS}','%l','%m')
- 运行:
logging.config= classpath:log4j.properties
private static Logger logger = Logger.getLogger(TestLog4jApplication.class);
public static void main(String[] args) {
logger.info("log4j----------------\n");
SpringApplication.run(TestLog4jApplication.class, args);
}