1.spring的特点
-
非侵入式
:基于Spring开发的应用中的对象可以不依赖于Spring的API。 -
控制反转
:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架. -
依赖注入
:DI——Dependency Injection,是指依赖的对象不需要手动调用setXXX方法去设置,而是通过配置赋值。 -
面向切面编程
:AOP——Aspect Oriented Programming,在不修改源代码的基础上进行功能扩展。 -
容器
:Spring是一个容器,因为它包含并且管理应用对象的生命周期。 -
组件化
:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。 -
一站式
:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的JDBCTemplate)。
2.spring的下载位置
最新正式发布版下载地址:JFrog
3.ioc在spring容器中的实现
beanfactory
applicationcontext
4.属性注入
setter注入在对应的xml文件进行对应的数据传递
构造器注入
特殊值的处理 若字面值中包含特殊字符,可以使用<![CDATA[ ]]>把字面值包裹起来
p名称空间,c名称空间
5.外部bean的作用就是当bean的属性是一个其他类型的对象是,可以在property或<constructor-arg>标签中通过ref属性或ref子标签引用IOC容器中配置好的该类型的bean,ref的属性值指定为引用的bean的id值。
内部bean当bean实例仅仅给一个特定的属性使用时,可以将其声明为内部bean。内部bean声明直接包含在<property>或<constructor-arg>元素里,不需要设置id。
级联属性当bean的属性是一个对象,我们可以通过配置当前bean的方式给属性中对象的属性赋值,即给属性的属性赋值,这种方式我们称为给级联属性赋值。
集合属性的赋值
6.自动装配
手动装配:以value或ref的方式明确指定属性值都是手动装配。
自动装配:根据bean标签的autowire属性指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。
-
自动装配的规则,即autowire的属性值有:
-
no或default:不自动装配
-
byName:根据bean的属性名称自动装配,以当前bean的属性名作为id从IOC容器中寻找以实现装配。找到则装配,找不到则不装配。
-
byType:根据bean的属性类型自动装配。找到一个则装配,找到多个则报错,找不到则不装配。
-
constructor:根据bean的属性的构造器自动装配,不推荐使用。
7.工厂bean
Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。普通bean设置的类型就是返回的类型;工厂bean设置的类型可以和返回的类型不一样,其返回的类型通过该工厂bean的getObject方法指定。
创建工厂bean必须实现org.springframework.beans.factory.FactoryBean接口。
8.bean的作用域
类别 | 说明 |
---|---|
singleton | 在Spring的IOC容器中仅存在一个Bean实例 |
prototype | 每次调用getBean方法都返回一个新的Bean实例 |
request | 每次HTTP请求都会创建一个新的Bean实例,该作用域仅适用于WebApplicationContext环境 |
session | 同一个Session会话共享一个Bean实例,该作用域仅适用于WebApplicationContext环境 |
9.bean的生命周期
-
通过构造器或工厂方法创建bean实例
-
为bean的属性设置值和对其他bean的引用
-
将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法
-
调用bean的初始化方法
-
将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法
-
bean可以使用了
-
当容器关闭时调用bean的销毁方法
10.bean的开发方式
基于xml的方式开发
基于注解的方式进行开发
完全注解的开发创建配置类
@Configuration // 配置类标志注解
@ComponentScan(basePackages = "com.atguigu") // spring包扫描
@PropertySource("classpath:jdbc.properties") // 读取属性配置文件
@EnableTransactionManagement // 开启事务注解
11.spring的aop
代理模式分为动态代理,静态代理
动态代理的作用就是创建一个类在使用另一个类将这个类进行实现,将里面的方法重写进行增强的处理
动态代理proxy,cglib,jdk的动态代理
cglib动态代理是第三方动态代理,不是JDK内置的动态代理.JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
-
Cglib和jdk动态代理的区别?
1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理
-
什么时候用cglib什么时候用jdk动态代理?
1、目标对象生成了接口 默认用JDK动态代理
2、如果目标对象使用了接口,可以强制使用cglib
3、如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换
动态代理的实现方式
-
基于接口实现动态代理: JDK动态代理
-
基于继承实现动态代理: Cglib、Javassist动态代理
12.spring的aop
通知类型就是在对应的方法上面添加通知类型的注解进行处理
使用就是先声明切入点表达式,在对方法进行通知类型的处理
springaop的实现方式
基于注解开发完成
基于xml文件的配置完成
13.操作数据库的jdbctemplate
public class JdbcTemplateTest {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans-jdbc.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) ioc.getBean("jdbcTemplate");
/*
测试增删改
*/
@Test
public void testUpdate(){
//写sql语句
String sql = "insert into employee(last_name,email,salary) values(?,?,?)";
//调用JdbcTemplate中的update方法
jdbcTemplate.update(sql,"雷军","leijun@xiaomi.xom",9999.00);
}
}
批量处理增删改
-
JdbcTemplate.batchUpdate(String, List<Object[]>)
-
Object[]封装了SQL语句每一次执行时所需要的参数
-
List集合封装了SQL语句多次执行时的所有参数
-
/*
测试批量增删改
*/
@Test
public void testBatchUpdate(){
//写sql语句
String sql = "insert into employee(last_name,email,salary) values(?,?,?)";
//创建一个List
List<Object[]> batchArgs = new ArrayList<>();
Object[] arg1 = new Object[]{"李某宏","liyanhong@baidu.com",8888.00};
Object[] arg2 = new Object[]{"刘某东","liuqiangdong@jd.com",7777.00};
Object[] arg3 = new Object[]{"张某鸣","zhangyiming@douyin.com",6666.00};
batchArgs.add(arg1);
batchArgs.add(arg2);
batchArgs.add(arg3);
//调用JdbcTemplate中的批处理方法
jdbcTemplate.batchUpdate(sql,batchArgs);
}
查询数据
查询单行
/*
测试获取一行数据
*/
@Test
public void testGetOne(){
//写sql语句
String sql = "select id,last_name lastName,email,salary from employee where id = ?";
//创建RowMapper对象
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);
//调用JdbcTemplate中的queryForObject方法
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);
System.out.println(employee);
}
查询多行
/*
测试获取多行数据
*/
@Test
public void testGetAll(){
//写sql语句
String sql = "select id,last_name lastName,email,salary from employee";
//创建RowMapper对象
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);
//调用JdbcTemplate中的query方法
List<Employee> employees = jdbcTemplate.query(sql, rowMapper);
//遍历
for (Employee employee : employees) {
System.out.println(employee);
}
}
14.spring的事务
基于注解开发的事务
-
在需要添加事务的方法上添加@Transactional注解
-
事务的传播行为就是在对应的transaction注解后面传播行为属性
事务的传播行为
传播属性 | 描述 |
---|---|
REQUIRED | 如果有事务在运行,当前的方法就在这个事务内运行;否则就启动一个新的事务,并在自己的事务内运行。 |
REQUIRES_NEW | 当前的方法必须启动新事务,并在自己的事务内运行;如果有事务正在运行,应该将它挂起。 |
SUPPORTS | 如果有事务在运行,当前的方法就在这个事务内运行,否则可以不运行在事务中。 |
NOT_SUPPORTED | 当前的方法不应该运行在事务中,如果有运行的事务将它挂起 |
MANDATORY | 当前的方法必须运行在事务中,如果没有正在运行的事务就抛出异常。 |
NEVER | 当前的方法不应该运行在事务中,如果有正在运行的事务就抛出异常。 |
NESTED | 如果有事务正在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在它自己的事务内运行。 |
基于xml开发
15.事务的并发问题
脏读在事务进行提交但是读取的数据是未提交之前的数据
幻读向表中插入数据但是查询时查询不到,在次插入发现已经插入了
不可重复读 前后读取一条数据发现数据是不可重复的
16.事务的隔离级别事务与事务之间是隔离的,互不相关
-
读未提交
:READ UNCOMMITTED允许Transaction01读取Transaction02未提交的修改。里面的事务并发问题有脏读,幻读,不可重复读
-
读已提交
:READ COMMITTED要求Transaction01只能读取Transaction02已提交的修改。事务并发问题有幻读,不可重复读
-
可重复读
:REPEATABLE READ确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。事务并发问题有幻读。解决事务并发的问题使用mvcc方式与原子性
-
串行化
:SERIALIZABLE确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
mysql默认的事务隔离级别可重复读,Oracle的默认事务隔离级别是读已提交
spring的事务隔离级别的设置使用在@Transactional的isolation属性中设置隔离级别
17.事务的异常回滚
-
@Transactional注解中设置回滚的属性
-
rollbackFor或rollbackForClassName属性:指定遇到时必须进行回滚的异常类型,可以为多个。
-
如果是运行时异常,默认都是回滚的,如果是检查型异常,不回滚
-
如果想在发生指定的运行时异常出现时回滚,则使用rollbackfor进行设置
-
如果想在发生任何的检查型异常都回滚 rollbackfor=java.lang.Exception.class
-
-
noRollbackFor或noRollbackForClassName属性:指定遇到时不回滚的异常类型,可以为多个。
-
事务的超时间timeout,只读readonly
18.spring5的新特性
框架自带log4j2
支持了jsr