Spring学习笔记

概述

  1. 轻量级/开源JavaEE框架
  2. 解决企业应用开发复杂性
  3. 两核心:IOC、AOP
  1. 方便解耦,简化开发
  2. AOP编程
  3. 方便测试
  4. 降低API使用难度
  5. 支持事务
  6. 方便整合其他框架

Spring依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.5.RELEASE</version>
</dependency>

Junit依赖

创建普通类,接口

创建spring配置文件

ClassPathXmlApplicationContext

IOC

创建对象交给Spring

注入方式

  1. Setter
  2. 构造注入
  3. P命名空间

<bean id="student" class="org.example.pojo.Student" autowire="byName|byType">

多配置文件

<!--包含多个配置文件-->
<!--    <import resource="classpath:base03/applicationContext_school.xml"></import>-->
<!--    <import resource="classpath:base03/applicationContext_student.xml"></import>-->
    <!--通配符配置多个-->
    <import resource="classpath:base03/applicationContext_*.xml"></import>

注解

  1. 加入spring注解依赖(spring-context时会把注解依赖自动加入spring-aop)

<!--    组件扫描器,1.可指定多个包用,隔开,2.可以多次使用标签引入多个包3.可以指定父包,会自动扫描子包-->
<context:component-scan base-package="org.example"></context:component-scan>

  1. 类中加入注解

//@Component(value = "myStudent")
//@Repository 持久层
//@Service 业务层
//@Controller 控制器
@Component("myStudent")
//@Component

成员变量或者setter方法注解

//    @Autowired引用类型注解,required默认true找不到报错
//    @Autowired(required = false)
//    @Qualifier("mySchool-1")
//    @Resource默认byName,没有则byType
    @Resource(name="school")

  1. 在spring配置文件中加入组件扫描器

AOP

动态代理

  1. 创建目标类,增强
  1. JDK,创建InvocationHandler接口的实现类,在这个类实现给目标类方法增强

public class InvocationHandlerImpl implements InvocationHandler {
    private Object target;//SomeServiceImpl
    public InvocationHandlerImpl(Object target){
        this.target=target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res=null;
        ServiceTool.doLog();
//        执行目标对象方法
        method.invoke(target,args);//doSome()doOther()
        ServiceTool.doTran();
        return res;
    }
}

B.使用Proxy类,创建代理对象,实现创建对象的能力

//        创建目标对象
        SomeService target = new SomeServiceImpl();
//        创建InvocationHandlerImpl
        InvocationHandler handler=new InvocationHandlerImpl(target);
//创建Proxy代理对象
        SomeService proxy = (SomeService)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);
//通过代理执行方法
        proxy.doSome();

Spring面向切面

Aspectj、Spring

@Before(value = "execution(* *..*.do*(..))")//前置通知

public void myBefore(JoinPoint jp) {
    System.out.println(jp.getSignature());
    System.out.println("切面功能,目标方法执行之前输入时间:" + new Date());
}

JDBCTemplate

事务管理

  1. 什么是事务

事务是指一组sql语句的集合,集合有多条sql语句可能是insert,update,select,delete,我们希望这些多个sql语句都能成功,或者失败,这些sql的执行是一致的,作为一个整体执行。

  1. 什么时候使用

当我的操作涉及得到多个表,或者多个sql语句的insert,update,delete。需要保证这些语句都是成功才能完成我的功能,或者都是失败,保证操作符合要求的。

在java中哪里写事务控制事务?放在service业务方法中,因为业务方法会调用多个dao方法执行多个sql。

  1. 通常使用JDBC访问数据库,还是mybatis访问数据库是怎么处理事务

Jdbc:conn.startTransaction()  conn.commit()  conn.rollback()

Mybatis:sqlSession.commit()  sqlSession.rollback()

  1. 上面事务处理方式有什么不足

A不同数据库访问技术,处理事务对象方法不同,需要了解不同数据库访问技术使用事务的原理

B掌握多种数据库访问技术的事务处理逻辑,什么时候提交事务,什么时候回滚事务

C处理事务的多种方法

总结:就是多种数据库访问技术,有不同的事务处理机制,对象,方法

  1. 怎么解决

Spring提供一种处理事务的统一模型,能使用统一步骤,完成多种不同数据库访问技术的事务处理,使用spring的事务处理机制,可以完成hibernate,mybatis访问数据库的事务处理

  1. 处理事务,需要怎么做,做什么

Commit close 回滚事务

接口:PlatformTransactionManager,定义了事务的重要方法,commit,close ,rollback

实现类:mybatis访问数据库,spring创建的是DataSourceTransactionManager

Hibernate:HibernateTransactonManager

怎么使用:告诉spring使用的是哪种数据库访问技术,使用<bean>声明数据库访问技术对应的实现类

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

业务需要什么样的事务,说明事务的类型

  1. 事务隔离级别,4个值

read_uncommited读未提交,未解决并发问题,

READ_Commited读已提交,解决脏读,存在不可重复读与幻读

Reapeat——read:可重复读,解决脏读,不可重复读,存在幻读

Serializable:串行化,不存在并发问题

  1. 事务超时时间,表示一个方法最长执行时间,如果方法执行超过了这个时间,事务回滚,单位秒,默认-1
  2. 事务传播行为,7个:

PROPAGATION_REQUIRED:指定的方法在事务中执行,若当前存在事务,就加入到当前事务中,若当前没有事务就创建一个事务,最常见,也是spring默认事务传播行为

PROPAGATION_REQUIRES_NEW:方法任何情况都创建新的事务执行,当前存在就挂起,直到新事务完成

PROPAGATION_SUPPORTS:方法有事务就当前事务中执行,也可以非事务方式执行

当业务执行成功,没有异常抛出,当方法执行完毕,spring咋方法执行后提交事务

当业务方法执行时异常,spring执行回滚,调用事务管理器的rollback

运行时异常:RuntimeException和他的子类都是运行时异常,例如:NullPointer、NumberFormat

当业务抛出非运行异常,主要是受查异常时,提交事务

  1. 管理事务,事务管理和它的实现类
  2. Spring的事务时一个统一模型
  1. 指定要使用的事务管理器实现类,使用<bean>
  2. 指定哪些类,哪些方法需要加入事务的功能
  3. 指定方法需要的隔离级别,传播行为,超时时间

我们要做的是:告诉spring项目类的信息,方法名称,方法事务传播行为

Spring提供事务处理方式

  1. 适合中小项目,注解方案,spring框架自己用aop实现给业务方法增加事务的功能@Transactional放在public方法上面,表示当前方法有事务,给注解属性赋值,隔离级别isolation=Isolation.DEFAULT,传播行为propagation=Propagation.REQUIRED,只读readOnly=false超时,rollbackFor异常类数组,rollbackForClassName异常类名,noRollbackFor
  1. 声明事务管理器对象<bean DataSourceTransactionManager>
  2. 开启事务注解驱动,告诉spring我要使用注解的方式管理事务,spring使用aop机制,创建@Transactional所在的类的代理对象,给方法加入事务功能
  3. 方法上使用@Transactional

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--指定数据源,数据库-->
    <property name="dataSource" ref="druidDataSource"></property>
</bean>
<!--开启事务注解驱动,告诉spring使用注解管理事务,创建代理对象-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

大型项目

<tx:advice id="myAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT"
                   rollback-for="org.example.exception.NotEnoughException,java.lang.NullPointerException"/>
        <tx:method name="add*" propagation="REQUIRES_NEW"/>
        <tx:method name="modify*" propagation="REQUIRES_NEW"/>
        <tx:method name="remove*" propagation="REQUIRES_NEW"/>
        <!--统配,SUPPORTS事务可以有可以么有-->
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

<!--    配置AOP-->
<aop:config>
    <!--        配置切入点-->
    <aop:pointcut id="pointcutTX" expression="execution(* *..service..*.*(..))"></aop:pointcut>
    <!--        配置增强-->
    <aop:advisor advice-ref="myAdvice" pointcut-ref="pointcutTX"></aop:advisor>
</aop:config>

脏读:读取了另一事务修改尚未提交的修改

不可重复读:执行一个事务两次或以上读取数据数据,但每次读取得到的数据不同

幻读:执行一个事务两次或以上,读取的数据记录不一样

WEB中使用容器对象

只需创建一次,放入全局作用域,servletContext

监听器,当全局作用域对象时,创建容器

ServletContext。setAttribute(key,value),可以使用框架的ContextLoaderListener

<!--    监听器对象依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

<!--    注册监听器,默认读取/WEB-INF/applicationContext.xml-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

//        创建spring容器对象
//        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        WebApplicationContext context = null;
//        获取ServletContext中的容器对象
//        String key="ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE";
//        Object obj=getServletContext().getAttribute(key);
//        if(obj!=null){
//            context=(WebApplicationContext)obj;
//        }

//        使用框架的方法获取容器对象
        ServletContext sc = getServletContext();
        context = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值