Spring5新特性
日志封装
引入jar包
创建 log4j2.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?><!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --><!--Configuration后面的status用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出--><configuration status="DEBUG"> <!--先定义所有的appender--> <appenders> <!--输出日志信息到控制台--> <console name="Console" target="SYSTEM_OUT"> <!--控制日志输出的格式--> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </console> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <!--root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认的日志输出--> <loggers> <root level="info"> <appender-ref ref="Console"/> </root> </loggers></configuration> @Nullable 注解
@Nullable注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性值可以为空,参数值可以为空
注解用在方法上面,方法返回值可以为空
注解使用在方法参数里面,方法参数可以为空
注解使用在属性上面,属性值可以为空
可实验下面的代码
函数式风格 GenericApplicationContext
@Test public void testGenericApplicationContext(){ //1.创建GenericApplicationContext对象 GenericApplicationContext context = new GenericApplicationContext(); context.refresh();// context.registerBean(User.class,() -> new User()); context.registerBean("user1",User.class,() -> new User()); // public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {// Nullable前面带它的参数值可以为空,如context.registerBean(User.class,() -> new User());中的第一个参数就没写,也是可以创建的。当然你写了也可以 // 获取spring注册的对象 User user = (User)context.getBean("user1"); System.out.println(user); }
还有些新特性不确定,还是先别上车了。需要的时候在进行学习即可
总结
Spring框架概述
(1)轻量级开源JavaEE框架,为了解决企业复杂性,两个核心组成:IOC和AOP
IOC控制反转,依赖注入
Spring5.2.6稳点的版本
IOC容器
(1)IOC底层原理(工厂、反射等)
先通过 XML 解析来加载 spring.xml 配置文件,然后使用反射机制调用无参构造函数动态创建对象,并调用 setter 方法完成对象属性的赋值,最后将创建好的对象放在一个类似于 HashMap 的容器里,调用 getBean 方法获取对象时,相当于 map.get(id) 返回一个对象。
(2) IOC接口(BeanFactory)
- BeanFactory:IOC容器基本实现,是spring内部使用接口,不提供开发人员使用。加载配置文件时不会创建对象,使用对象时才会创建对象(懒汉式加载对象)。
- ApplicationContext:BeanFatory的子接口,提供更多更强大的功能,一般供开发人员进行使用。加载配置文件时就创建对象(饥汉式加载对象)。
(3)IOC操作Bean管理(基于注解)
创建对象
- @Component 普通用法
- @Service 用于service业务逻辑层
- @Controller 用于web层
- @Repository 用于DAO持久层
注入属性
@Autowired:根据属性类型进行自动装配
Aop
(1) AOP底层原理
动态代理,有接口(JDK动态代理),没有接口(CGLIB动态代理)
(2)关键术语
切入点:实际增强的方法
增强(通知):方法增强的部分
切面:将通知应用到切入点的过程
(3)基于Aspect]实现AOP操作
创建被代理类
创建代理类,通过@Component
在代理类,上添加注解@Aspect
在Spring配置文件中开启生产代理对象
配置不同类型的通知
JdbcTemplate
(1)使用JdbcTemplate实现数据库curd操作
创建UserDao接口,创建实现类
1、注入jdbcTemplate
2、创建添加的方法
3、创建sql语句
4、调用方法实现jdbcTemplate.update(sql, args);
CRUD其余类似
创建UserService调用实现类方法
创建测试类调用UserService逻辑方法
1.解析xml文件
2.得到对象
(2)使用JdbcTemplate实现数据库批量操作
1.将参数放到一个集合里
2.调用jdbcTemplate.batchUpdate(sql, batchArgs);进行批量处理
3.设置参数添加到集合
4.实施
事务管理
(1)事务概念
事务是数据库操作基本单元,逻辑上一组事物要么同时成功要么同时失败,只要有一个失败,那么所有操作都失败
(2)传播行为
传播行为:事务B方法被事务A方法调用时,事物B方法应该如何进行
(3)隔离级别:
如果事务并发可能会出现脏读,不可重复读,幻读等情况。为了避免发生这种情况可以通过事务的隔离级别来解决这个问题
分别是
读未提交:什么都避免不了
读已提交:事物B只能在事物A修改过并且提交过才能读取到A修改过的数据,能避免脏读
==可重复读(Mysql默认事物隔离级别)==:事务B只能在事务A修改过提交过后,自己也提交后,才能读取到事务A修改过的数据
可串行化:事务的最高级别。给操作的记录上一个共享锁(读写锁),即当读某条记录时就占用这条记录的读锁,此时其它事务一样可以申请到这条记录的读锁来读取,但是不能写(读锁被占的话,写锁就不能被占;读锁可以被多个事务同时占有)
(3)完全注解方式实现声明式事务管理
声明注解类
package com.caq.spring5.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration //配置类 @ComponentScan(basePackages = "com.caq") //扫描com.caq包下所有 @EnableTransactionManagement //开启事物 public class TxConfig { //创建数据库连接池 @Bean public DruidDataSource getDruidDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///user_db"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; } // JdbcTemplate对象 @Bean public JdbcTemplate getJdbcTemplate(DataSource dataSource) { // 到ioc容器中根据数据类型找到dataSource JdbcTemplate jdbcTemplate = new JdbcTemplate(); // 注入dataSource jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } //声明事物管理器 @Bean public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
开启事物
package com.caq.spring5.service; import com.caq.spring5.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service //生成UserService对象 @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ) //开启事物,并设置事物相关参数 public class UserService { // 注入dao @Autowired private UserDao userDao; public void accountMoney(){ userDao.reduceMoney(); int i = 10/0; userDao.addMoney(); } }
测试
@Test public void test3(){ ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class); UserService userService = context.getBean("userService", UserService.class); userService.accountMoney(); }