Spring知识点总结

本文介绍了Spring作为Java EE开发框架的核心特性,包括IoC和AOP,事务管理、轻量级设计、一站式解决方案,以及如何通过Maven配置、DI实现和AOP注解来简化项目开发。涵盖了Spring的优势、项目实现步骤和事务处理详解。
摘要由CSDN通过智能技术生成

1. 什么是spring
Spring 被称为 J2EE 的春天,是一个开源的轻量级的 Java 开发框架, 具有控制反转(IoC)和面向切面(AOP)两大核心。Java Spring 框架通过声明式方式灵活地进行事务的管理,提高开发效率和质量

Spring框架是个轻量级的Java EE框架。所谓轻量级,是指不依赖于容器就能运行的。Struts、Hibernate也是轻量级的。Spring以IoC、AOP为主要思想,其中IoC,Inversion of Control 指控制反转或反向控制。在Spring框架中我们通过配置创建类对象,由Spring在运行阶段实例化、组装对象。AOP,Aspect Oriented Programming,面向切面编程,其思想是在执行某些代码前执行另外的代码,使程序更灵活、扩展性更好,可以随便地添加、删除某些功能。Servlet中的Filter便是一种AOP思想的实现。
  Spring同时也是一个“一站式”框架,即Spring在JavaEE的三层架构[表现层(Web层)、业务逻辑层(Service层)、数据访问层(DAO层)]中,每一层均提供了不同的解决技术。如下:

表现层(Web层):Spring MVC

业务逻辑层(Service层):Spring的IoC

数据访问层(DAO层):Spring的jdbcTemplate

1.2 spring优势
(1)方便解耦,简化开发
(2)AOP编程支持
(3)声明式事务的支持
(4)方便集成各种优势框架
(5)降低JAVAEE API的使用难度
(6)JAVA源码是经典学习案例

在这里插入图片描述

spring项目实现步骤
1.创建maven项目

2.加入maven的依赖

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

    <!--单元测试-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!--spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>
    </dependencies>

<!--    可加可不加-->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3.创建类(接口和他的实现类)、

package com.bjpowernode.service;

public interface SomeService {
    void doSome();
}
package com.bjpowernode.service.impl;

import com.bjpowernode.service.SomeService;

public class SomeServiceImpl implements SomeService {

    public SomeServiceImpl() {
        System.out.println("SomeServiceImpl的无参构造方法");
    }

    @Override
    public  void doSome(){
        System.out.println("doSome方法执行啦");
    }
}

4.创建spring需要使用的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

    <!--
       告诉spring创建对象,
       声明bean,就是告诉spring要创建某个类的对象
       id:对象的自定义名称,唯一值。spring通过这个名称找到对象
       class:类的全限定名称(不能是接口,因为spring是反射机制创建对象,必须使用类)
       spring就完成SomeService someService=new SomeServiceImpl();
       spring是把创建好的对象放入到map中,spring框架有一个map存放对象的
          springMap.put(id的值,对象)
          例如springMap.put("SomeService","new SomeService")
          一个beans值
       -->

    <bean id="SomeService" class="com.bjpowernode.service.impl.SomeServiceImpl"/>

    <bean id="SomeService1" class="com.bjpowernode.service.impl.SomeServiceImpl" scope="prototype"/>

    <!--
    spring能创建一个非自定义类的对象,创建一个存在的某个类的对象
    -->
    <bean id="mydate" class="java.util.Date"/>
</beans>

5.测试spring创建的类

每一个@Test能够单独运行

package com.bjpowernode;

import com.bjpowernode.service.SomeService;
import com.bjpowernode.service.impl.SomeServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;

public class Test1 {
    @Test
    public  void test01(){
        SomeService service=new SomeServiceImpl();
        service.doSome();
    }
/*

spring会默认创建对象的时间:在创建spring的容器时,会创建配置文件中所有的对象
//当创建两个bean标签时,SomeServiceImpl的无参构造方法执行了两次
spring创建对象:默认调用的是无参构造方法
*/

 @Test
    public void test02(){
        //使用spring容器创建对象
        //1.指定spring配置文件名称
        String config="beans.xml";
        //2.创建表示spring容器对象,ApplicationContext
        //ApplicationContext就是表示spring容器,通过容器获取对象
        //ClassPathXmlApplicationContex:表示从类路径中加载spring的配置文件
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);

        //3.从容器中获取某个对象,你要调用对象的方法
        //getBean("配置文件中的bean的id值")
        //(SomeService)将getBean("SomeService")内容强转成SomeServic类型
        SomeService service=(SomeService) ac.getBean("SomeService");
        //4.使用spring创建好的对象
        service.doSome();//当创建两个bean标签时,SomeServiceImpl的无参构造方法执行了两次


    }

    //获取spring容器中java对象的信息

    @Test
    public  void test03(){
        String config="beans.xml";
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);
        //使用spring提供的方法,获取容器中定义的对象数量
        int nums=ac.getBeanDefinitionCount();
        System.out.println("容器中定义的对象数量"+nums);
        //容器中每个定义的对象的名称
        String names[]=ac.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

    }

    //获取一个非自定义的类的对象
    @Test
    public void test04(){
        String config="beans.xml";
        ApplicationContext ac=new ClassPathXmlApplicationContext(config);
        //使用getBean();
        //(Date):强制类型转换
        Date my=(Date) ac.getBean("mydate");
        System.out.println("Date:"+my);
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

di:依赖注入,表示创建对象,给属性赋值
di的实现语法有两种
1.在spring的配置文件中,使用标签和属性完成,叫做基于XML的di实现(使用较少)

2.使用spring中的注解,完成属性赋值,叫做基于注解的di实现
di语法分类:

1.set注入(设置注入):spring调用类的set方法,在set方法可以实现属性的赋值
(使用set注入时,构造方法在set方法之前执行。set内部的方法可以自定义,构造后会显示出来)
80左右都是使用set注入

2.构造注入,spring调用类的有参构造方法,创建对象。在构造方法中完成赋值。

2.基于注解的di:通过注解完成java对象创建,属性赋值
使用注解步骤:
1.加入maven依赖spring-context,在加入spring-contextd的同时,间接加入spring-aop依赖使用注解必须使用spring-aop依赖

2.在类中加入spring的注解(多个不同功能的注解)

3.在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置

在这里插入图片描述

需要学习的注解

@Component
@Respotory
@Service
@Controller
@Value
@Autowired
@Resource

1.@Component
2.@Respotory
3.@Service
4.@Controller

@Component:创建对象,等同于的功能
属性:value就是对象的名称,也就是bean的id值
value的值是唯一的。穿创建的对象在整个spring容器中就一个
位置:在类上面。

  @Component(value="mystudent")  等同于
 <bean id="myStudent" class="com.bjpowernode.ba01.Student">

和@Component功能一致的注解还有

1.@Repository(用在持久层类的上面):放在dao的实现类上面,
表示创建dao对象,dao对象是能访问数据库的。

2.@Service(用在业务层上面):放在service的实现类上面
创建service对象,service对象是做业务处理,可以有事务等功能。

3.@Controller(用在控制器上面):放在控制器(处理器)类的上面,创建控制器对象
控制器对象,能够接受用户提交的参数,显示请求的处理结果

以上三个注解的使用语法和@Component使用方法一样。但还有额外功能
当不知道具体使用的地方(持久层,业务层,控制器)使用@Component
*/

//使用value属性值,指定对象名称
//@Component(value="myStudent")

//省略value
//@Component("myStudent")


5.@Value

/*
@Value:简单类型属性赋值
属性:value是string类型的,表示简单类型的属性值
位置:1.在属性定义的上面,无需set方法,推荐使用
2.在set方法上面

@Value("张飞")
private String name;
@Value( "29")
private int age;

 */

5.@Autowired
/*
引用类型
@Autowired:spring框架提供的注解,实现引用类型的赋值
spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
@Autowired:默认使用的是byType自动注入

位置:
1.在属性定义的上面,无需set方法,推荐使用
2.在set方法上面,需要做的是:
1.属性上面加入@Autowired
2.在属性上面加入@Qualifier(value=“bean的id”):表示使用指定名称bean完成赋值。

如果要使用byName方式
*/
//声明一个引用类型

 @Autowired
 private School school;
 @Value("nana")
 private String name;
 @Value("35")
 private int age;

@Resource
/*
引用类型
@Resource 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值
使用的也是自动注入原理,支持byName,byType,默认是byName
位置:1.在属性定义的上面,无需set方法,推荐使用
2,在set方法上面
*/

//默认是byName,byName不可使用,会使用byType

@Resource
private School school;

private String name;

private int age;

配置文件和注解方式使用选择:
需要经常改动就使用配置文件形式
不需要经常改动就使用注解方式
(通过分析可以发现,配置文件形式把复制和主类完全分开,分离特别彻底,需要改动时,把配置文件中的属性改变一下就完成了)但是注解方式,开发简单,易于维护,同时在查看相关信息时,方便查看。

现在开发一般注解为主(方便),配置文件为辅

aop
1.动态代理
实现方式:jdk动态代理,使用Jdk中proxy,Method,InvocationHandle创建代理对象,jdk动态代理要求目标类必须实现接口。

cglib动态代理:第三方的工具库,创建代理对象,原理是继承。通过继承目标类,创建子类。子类对象就是代理对象。要求目标类不能是final的,方法也不能是final的

2.动态代理作用:
(1)在目标类源码不改变的情况下,增加功能
(2)减少代码的重复
(3)专注业务逻辑代码
(4)解耦合,让你的业务功能和日志,事务非业务功能分离

3.aop:面向切面编程,基于动态代理,可以使用jdk,cglib两种代理方式
AOP就是动态代理规范化,把动态代理的实现步骤,方式都定义好了,让开发人员用一种统一的方式,就是动态代理。

4.AOP(Aspect Orient Programing)面向切面编程
Aspect:切面;给你的目标类增加的功能,就是切面。像日志,事务等
切面的特点:一般都是非业务的方法,独立使用的
Orient:面向,对着。
Programing:编程

OOP:面向对象编程
怎么理解面向切面编程。
(1)需要在分析项目功能时,找出切面
(2)合理安排切面的执行时间(在目标方法前,还是目标方法后)
(3)合理的安全切面执行的位置,在哪个类,哪个方法增加增强功能。

术语:
(1)Aspect:切面,表示增强的功能,就是一堆代码。完成某一个功能。非业务功能,常见的切面功能有日志,事务,统计信息,参数检查,权限验证
(2)JoinPoint:连接点,连接业务方法和切面的位置,就某类中的业务方法(一个)
(3)PointCut:切入点,指多个连接点方法的集合。多个方法(多个)
(4)目标对象:给哪个类的方法增加功能,这个类就是目标
(5)Advice:通知,通知表示切面功能执行的时间。

切面三要素:
(1)切面的功能代码,切面干什么。
(2)切面的执行位置,使用PointCut表示切面执行的位置
(3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是之后

5.AOP的实现
aspectJ框架可以实现aop,并且集成在了spring框架中,实现方式
1.使用xml的配置文件:配置全局事务
2.使用注解,我们在项目中要做到aop功能,一般都需要注释,aspect有5个注释

6.Aspectj框架的使用
(1)切面的执行时间,这个执行时间在规范中叫做Advice(通知,增强)
在aspectj框架中使用注解表示,也可以使用xml配置。
@Before
@AfterReturning
@Around
@AfterThrowing
@After

AspectJ的切入点表达式(重点)
AspectJ表达式原型:
execution(modifiers-pattern? ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
解释:
modifiers-pattern:访问权限类型
ret-type-pattern:返回值类型
declaring-type-pattern:包名类名
name-pattern(param-pattern):方法名(参数类型和参数个数)
throws-pattern:抛出异常类型
?:表示可选部分
也就是:
execution(访问权限,方法返回值,方法声明(参数),异常类型)

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution表达式中明显是方法的签名。注意:表达式中黑色文字表示可省略部分,各部分间用空格分开。在其中可以使用以下符号

  • 0至多个任意字符
    … 用在方法参数中,表示任意多个参数
    用在包名后,表示当前包及其子包路径
  • 用在类名后,表示当前类及其子类
    用在接口后,表示当前接口及其实现类。

举例:

execution(public* *(..))
指定切入点为:任意公共方法,
execution(* set*(..))
指定切入点为:任何一个以“set”开始方法
execution(*com.xyz,service.*.*(..))
指定切入点为:定义在service包里任意类的任意方法
execution(*com.xyz,service.*.*(..))
指定切入点为:定义在service包或者子包里的任意列的任意方法。“...”出现在类名称中时,后面跟“*”,表示包,子包下的所有类。
execution(* *..service.*.*(..))
指定所有包干的service子包下所有类(接口)中所有方法为切入点
execution(* *..service.*.*(..))
指定只有一级包下的service子包下所有类(接口)中所有方法为切入点

快速实现接口的实现类:alt+enter

aspectj实现aop基本步骤
1.新建maven项目

2.加入依赖
(1)spring依赖
(2)aspectj依赖
(3)junit单元测试

3.创建目标类:接口和他的实现类。要做的是给类种的方法增加功能

4.创建切面类:普通类
(1):在类上面加入@Aspect
(2)在类中定义方法,方法就是切面要执行的功能代码
在方法的上面加入aspectj中的通知注解,例如@Before
有需要指定切入点表达式execution()

5.创建spring的配置文件:声明对象,把对象交给容器统一管理
声明对象你可以使用注解或者xml配置文件
1)声明目标对象
2)声明切面对象
3)声明aspectj框架中自动代理生成器标签。
自动代理生成器:用来完成代理对象的自动创建功能。

6.创建测试类,从spring容器汇中获取对象(实际就是代理对象)
通过代理执行方法,实现aop的功能增强。

spring整合mybatis步骤:

mybatis使用步骤:
1.定义dao接口,studentDao

2.定义mapper文件,studentDao.xml

3.定义mybatis的主配置文件mybatis.xml

4.创建到代理对象,

studentDao dao=SqlSession.getMapper(studentDao.class);
List<student> students=dao.selectStudent();

要使用dao对象,需要使用getMapper()方法,

怎么能使用getMapper()方法,需要哪些条件
1.获取SqlSession对象,需要使用SqlSessionFactory的openSession()方法
2.创建SqlSessionFactory对象。通过读取mybatis的主配置文件,能够创建SqlSessionFactory对象
需要SqlSessionFactory对象,使用Factory能获取SqlSession,有了SqlSession就能有dao,目的就是获取dao对象Factory创建需要读取主配置文件

主配置文件

<!-- mybatis的主配置文件 -->
<configuration>

    <typeAliases>
        <package name="com.southwind.entity"/>
    </typeAliases>

    <!-- 配置mybatis运行环境 -->
    <environments default="development">
        <!-- 配置mysql环境 -->
        <environment id="development">
            <!-- 配置事务类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

3.mapper映射配置文件

<!-- 注册AccountMapper.xml -->
<mappers>
    <mapper resource="com/southwind/Mapper/AccountMapper.xml"></mapper>
    <mapper resource="com/southwind/reposity/AccountReposity.xml"></mapper>
    <mapper resource="com/southwind/reposity/StudentReposity.xml"></mapper>
    <mapper resource="com/southwind/reposity/ClassesReposity.xml"></mapper>
</mappers>

spring需要创建以下对象
1.独立的连接池类对象,使用阿里的druid连接池
2.SqlSessionFactory对象
3.创建出dao对象

spring与mybatis整合步骤
1.新建maven项目

2.加入maven依赖
1)spring依赖
2)mybatis依赖
3)mysql驱动
4)spring的事务依赖
5)mybatis和spring集成的依赖

3.创建实体类

4.创建dao接口和mapper文件

5.创建mybatis主配置文件

6.创建Sdervice接口和实现类,属性是dao

7.创建spring的配置文件:什么mybatis的对象交给spring创建
1)数据源
2)SqlSessionFactory
3)dao对象
4)声明自定义的service

8.创建测试类,获取service对象,通过service调用dao完成数据库的访问。

====================================================
spring事务处理
1.什么是事务
事务是指一组aql语句,集合中有多条sql语句可能都是insert,update,deiete,我们希望这些语句都能执行成功或者失败。这写语句执行都是一致的,作为一个整体执行。

2.在什么时候想到使用事务
当我们的操作涉及到多个表,或者多个sql语句时。需要保证这些语句都是成功才能完成功能,或者都失败,如转账
事务放在service层上,因为会调用多个dao方法,执行sql语句
在这里插入图片描述

3.处理事务需要做什么
spring处理事务模型,使用的步骤都是固定的,把事务的使用信息提供给spring就可以了
(1)事务内部提交,回滚事务,使用的事务管理器对象,代替你完成commit,rollback,事务管理器是一个接口和他的众多实现类
接口:platformTransactionManager,定义了事务重要方法commit,rollback,
实现类:spring把每一种数据库访问技术对应的事务处理类都创建好了
mybatis访问数据库:spring创建好的是DataSourceTransactionManger

怎么使用:需要告诉spring你是用哪种数据库访问技术,
怎么告诉:声明数据库访问技术对于的事务管理器实现类,在speing的配置文件中使用声明
例如,使用mybatis数据库:

<bean id=”xxx”  class=...DataSourceTransactionManger”>

(2)说明方法需要的事务
1.事务的隔离级别:4个, mysql默认是repeatable_read
用于控制高并发情况下对事务安全性的控制
read_uncommitted:读未提交,未解决任何并发问题
read_committed:读已提交,解决脏读,存在不可重复读与幻读
repeatable_read:可重复读,解决脏读、不可重复读,存在幻读
serializable:串行化,不存在并发问题

2.事务超时时间:表示一个方法最长执行时间,如果方法执行时间超过了时间,事务就回滚

3.事务的传播行为:控制业务方法是不是业务的,是什么样的业务事务的
需要掌握以下三个
propagation_required
propagation_requires_new
propagation supports

(3)提交事务,回滚事务的时机
1.当你的业务方法,执行成功,没有异常抛出,当方法执行完毕,spring在方法执行后提交事务。事务管理器commit
2.当你的业务方法抛出运行是异常,spring执行回滚,调用事务管理器的rollback
运行时异常的定义:RunTimeException 和他的子类都是运行时异常,;如NullPointException , NumberFormatException

3.当你的业务方法抛出运行时异常,主要是受查异常时,提交事务
受查异常:在你写代码时,必须处理的异常。例如IoException,SQLException

总结spring事务:

1.管理事务的是事务管理和他的实现类
2.spring的事务是一个统一模型
(1)指定要使用的事务管理器实现类,使用
(2)指定哪些类,哪些方法需要加入事务的功能
(3)指定方法需要的隔离级别,传播行为,超时。

你需要告诉spring,你项目中的信息,方法的名称,方法的事务传播行为。

spring事务注解

@Transactional注解:将事务组织到响应public方法中,实现事务管理

@Transactiona可选属性
propagation:用于设置事务传播属性。该属性类型为propagation枚举,默认值为

propagation.REQUIRED

isolation:用于设置事务的隔离级别。属性类型为isolation枚举,默认为isolation.REQUIRED

readOnly:用于设置该方法对数据库的操作是否是只读的。该属性为boolean,默认为false

timeout:用于设置本操作与数据库连接的超时时限。单位为秒,类型为int,默认为-1,及没有时限

rollback:指定事务回滚的异常类。类型为Class[],默认值为空数组。当然,若只有一盒异常类时,可以不使用数组

rollbackForClassName:指定需要回滚的异常类类名。类型为class[],默认为空数组。当然,若只有一个异常类时,可以不使用数组

noRollbackFor:指定不需要回滚的异常类。类型为class[],默认为空数组。当然,若只有一个异常类时,可以不使用数组

noRollbackForClassName:指定不需要回滚的异常类类名,类型为class[],默认为空数组。当然,若只有一个异常类时,可以不使用数组

使用@Transactional步骤:
1.需要声明事务管理器对象

<bean id=”xxx” class=”DataSourceTransactionManger”>

2.开启事务注解驱动,告诉spring框架,我需要使用注解方式管理事务
spring使用aop机制,创建@Transactional所在的类代理对象,给方法加入事务的功能。

类上加@Transactional,则类中所有方法都会加入事务处理
方法上加@Transactional,只有该方法会进行事务处理

spring给业务方法加入事务
在你的业务方法执行之前,先开启事务,在业务方法之后提交或会晕事务,使用aop的环绕通知(环绕通知不需要写,加上@Transactional注解后,spring就给你自动实现了)

@Around(“你要参加的事务功能的业务方法名称”)
object myAround(){
开启事务,spring给你开启
try{
buy(1001,10);
spring事务管理.commit();
}catch(Exception e){
  spring的事务管理.rollback()
}
}

3在你的方法上面加@Transactional

2.适合大型项目使用aspectj框架功能

实现步骤:都是在xml配置文件中实现
(1)要使用的是aspectj框架,需要计入依赖

<!-- aspectj依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

(2)声明事务管理器对象

<bean id=”xx”  class=”DataSourceTransactionManager”>

(3)声明方法需要的事务类型(配置方法的事务属性【隔离级别,传播行为,超时】)

(4)配置aop:指定哪些要创建的代理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值