• spring


    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的下载位置

    官网:Spring | Home

    最新正式发布版下载地址:JFrog

    3.ioc在spring容器中的实现

    beanfactory

    applicationcontext

    4.属性注入

    setter注入在对应的xml文件进行对应的数据传递

    构造器注入

    特殊值的处理 若字面值中包含特殊字符,可以使用把字面值包裹起来

    p名称空间,c名称空间

    5.外部bean的作用就是当bean的属性是一个其他类型的对象是,可以在property或标签中通过ref属性或ref子标签引用IOC容器中配置好的该类型的bean,ref的属性值指定为引用的bean的id值。

    内部bean当bean实例仅仅给一个特定的属性使用时,可以将其声明为内部bean。内部bean声明直接包含在元素里,不需要设置id。

    级联属性当bean的属性是一个对象,我们可以通过配置当前bean的方式给属性中对象的属性赋值,即给属性的属性赋值,这种方式我们称为给级联属性赋值。

    集合属性的赋值

    6.自动装配

    手动装配:以value或ref的方式明确指定属性值都是手动装配。

    自动装配:根据bean标签的autowire属性指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。

    • 自动装配的规则,即autowire的属性值有:

    1. no或default:不自动装配

    2. byName:根据bean的属性名称自动装配,以当前bean的属性名作为id从IOC容器中寻找以实现装配。找到则装配,找不到则不装配。

    3. byType:根据bean的属性类型自动装配。找到一个则装配,找到多个则报错,找不到则不装配。

    4. 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的生命周期

    1. 通过构造器或工厂方法创建bean实例

    2. 为bean的属性设置值和对其他bean的引用

    3. 将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法

    4. 调用bean的初始化方法

    5. 将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法

    6. bean可以使用了

    7. 当容器关闭时调用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

    1. public class JdbcTemplateTest {
    2. ApplicationContext ioc = new ClassPathXmlApplicationContext("beans-jdbc.xml");
    3. JdbcTemplate jdbcTemplate = (JdbcTemplate) ioc.getBean("jdbcTemplate");
    4. /*
    5. 测试增删改
    6. */
    7. @Test
    8. public void testUpdate(){
    9. //写sql语句
    10. String sql = "insert into employee(last_name,email,salary) values(?,?,?)";
    11. //调用JdbcTemplate中的update方法
    12. jdbcTemplate.update(sql,"雷军","leijun@xiaomi.xom",9999.00);
    13. }
    14. }

    批量处理增删改

    • JdbcTemplate.batchUpdate(String, List)

      • Object[]封装了SQL语句每一次执行时所需要的参数

      • List集合封装了SQL语句多次执行时的所有参数

    1. /*
    2. 测试批量增删改
    3. */
    4. @Test
    5. public void testBatchUpdate(){
    6. //写sql语句
    7. String sql = "insert into employee(last_name,email,salary) values(?,?,?)";
    8. //创建一个List
    9. List batchArgs = new ArrayList<>();
    10. Object[] arg1 = new Object[]{"李某宏","liyanhong@baidu.com",8888.00};
    11. Object[] arg2 = new Object[]{"刘某东","liuqiangdong@jd.com",7777.00};
    12. Object[] arg3 = new Object[]{"张某鸣","zhangyiming@douyin.com",6666.00};
    13. batchArgs.add(arg1);
    14. batchArgs.add(arg2);
    15. batchArgs.add(arg3);
    16. //调用JdbcTemplate中的批处理方法
    17. jdbcTemplate.batchUpdate(sql,batchArgs);
    18. }

    查询数据

    查询单行

    1. /*
    2. 测试获取一行数据
    3. */
    4. @Test
    5. public void testGetOne(){
    6. //写sql语句
    7. String sql = "select id,last_name lastName,email,salary from employee where id = ?";
    8. //创建RowMapper对象
    9. RowMapper rowMapper = new BeanPropertyRowMapper<>(Employee.class);
    10. //调用JdbcTemplate中的queryForObject方法
    11. Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);
    12. System.out.println(employee);
    13. }

    查询多行

    1. /*
    2. 测试获取多行数据
    3. */
    4. @Test
    5. public void testGetAll(){
    6. //写sql语句
    7. String sql = "select id,last_name lastName,email,salary from employee";
    8. //创建RowMapper对象
    9. RowMapper rowMapper = new BeanPropertyRowMapper<>(Employee.class);
    10. //调用JdbcTemplate中的query方法
    11. List employees = jdbcTemplate.query(sql, rowMapper);
    12. //遍历
    13. for (Employee employee : employees) {
    14. System.out.println(employee);
    15. }
    16. }

    14.spring的事务

    基于注解开发的事务

    1. 在需要添加事务的方法上添加@Transactional注解

    2. 事务的传播行为就是在对应的transaction注解后面传播行为属性

    事务的传播行为

    传播属性描述
    REQUIRED如果有事务在运行,当前的方法就在这个事务内运行;否则就启动一个新的事务,并在自己的事务内运行。
    REQUIRES_NEW当前的方法必须启动新事务,并在自己的事务内运行;如果有事务正在运行,应该将它挂起。
    SUPPORTS如果有事务在运行,当前的方法就在这个事务内运行,否则可以不运行在事务中。
    NOT_SUPPORTED当前的方法不应该运行在事务中,如果有运行的事务将它挂起
    MANDATORY当前的方法必须运行在事务中,如果没有正在运行的事务就抛出异常。
    NEVER当前的方法不应该运行在事务中,如果有正在运行的事务就抛出异常。
    NESTED如果有事务正在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在它自己的事务内运行。

    基于xml开发

    15.事务的并发问题

    脏读在事务进行提交但是读取的数据是未提交之前的数据

    幻读向表中插入数据但是查询时查询不到,在次插入发现已经插入了

    不可重复读 前后读取一条数据发现数据是不可重复的

    16.事务的隔离级别事务与事务之间是隔离的,互不相关

    1. 读未提交:READ UNCOMMITTED

      允许Transaction01读取Transaction02未提交的修改。里面的事务并发问题有脏读,幻读,不可重复读

    2. 读已提交:READ COMMITTED

      要求Transaction01只能读取Transaction02已提交的修改。事务并发问题有幻读,不可重复读

    3. 可重复读:REPEATABLE READ

      确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。事务并发问题有幻读。解决事务并发的问题使用mvcc方式与原子性

    4. 串行化: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

    1. JCP官网地址:The Java Community Process(SM) Program

    2.  JCP 官网可以查看所有 JSR 标准

  • 相关阅读:
    Android wifiMac地址显示异常坑
    Redisson的基本使用
    Kotlin - 协程构建器 CoroutineBuilder
    精通Java事务编程(7)-可串行化隔离级别之两阶段锁定
    玩转Linux与运维岗(31)
    go如何读取或设置os的环境变量
    Python itertools教程(python中的迭代器与组合迭代器)
    内网穿透工具frp使用入门
    程序员面试金典 - 面试题 17.17. 多次搜索
    利用pearcmd实现裸文件包含
  • 原文地址:https://blog.csdn.net/B__B_B/article/details/136676109