• 笔记——spring基本使用(控制反转IOC、面向切面编程AOP、声明式事务,事务隔离级别、事务传播)


    spring温习笔记


    Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
    Spring 的控制反转IOC、面向切面编程AOP等特性不多说。
    本文核心内容:搭建一个Spring Demo
    概要:想要启动spring这个大工厂,需要通过加载spring的核心配置文件类创建spring的核心类ApplicationContext,

    ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");这样spring就启动起来了。通过getBean方法可以手动获取Ban对象:

    ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    
    Student s=ac.getBean(Student.class);

    这样可以看出使用spring之前需要先将spring的xml核心配置文件编辑好,这块的配置这里只做简单的配置使用,不进行深度研究。
     

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	   xmlns:context="http://www.springframework.org/schema/context"
           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.1.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-4.1.xsd">
               
               	<!--通过该标签可以导入其他的xml文件  这样就可以将配置进行分开管理  -->
               <import resource="aop.xml"/>	<!--将aop的配置放到了该xml文件中  -->
               <import resource="tx.xml"/>	<!--将关于事务的配置放到该xml文件中  -->
               <!-- 扫描Component组件  -->
               <context:component-scan base-package="com"/>
               <context:component-scan base-package="haha"/>
    </beans>


    关于控制反转IOC:将我们平时对对象的创建和管理交给spring这个大工厂,由他在我们需要的时候给我创建并注入给我们,
    所以关于IOC的另一个说法就是D依赖注入,我们使用的对象需要依赖spring来注入到程序中,来做到集中管理,降低耦合的作用。
    在使用这一特性时要让spring知道需要管理那些类和注入到哪里,平时常用注解的方式来配置,注解的方式感觉便捷很多,
    在xml中开启组件扫描spring会自动扫描"com"包下的所有组件(Component、Controller、Service、Repository)
    添加了注解的类会被spring管理,在需要使用的地方添加声明一个该对象的引用,在该属性上添加注入的注解(@Autowired、@Resource)两者之间的区别:

    Autowired是自动注入,自动从spring的上下文找到合适的bean来注入
    Resource用来指定名称注入
    Qualifier和Autowired配合使用,指定bean的名称
    Service,Controller,Repository分别标记类是Service层类,Controller层类,数据存储层的类,spring扫描注解配置时,会标记这些类要生成bean。
    Component是一种泛指,标记类是组件,spring扫描注解配置时,会标记这些类要生成bean。
    上面的Autowired和Resource是用来修饰字段,构造函数,或者设置方法,并做注入的。而Service,Controller,Repository,Component则是用来修饰类,标记这些类要生成bean。

    import org.springframework.stereotype.Component;
    @Component
    public class TestComponentScan {
    
    
    	private String tname="DingZuoHeng";
    
    
    	public  TestComponentScan(){}
    	//private  TestComponentScan(){}
    	
    	public String getTname() {
    		return tname;
    	}
    	public void setTname(String tname) {
    		this.tname = tname;
    	}
    	
    }

    该类为需要被spring管理的component组件。

    import javax.annotation.Resource;
    import org.springframework.stereotype.Component;
    @Component
    public class Student {
    	@Resource
    	TestComponentScan testComponentScan;
    	public void haveClass(){
    		System.out.println("Student类中的haveClass方法执行。。。"+testComponentScan.getTname());
    	}
    }



    将上述组件注入到Student类中,启动spring并运行haveClass方法就可以看到控制台输出被注入类的信息。
    以上就是spring IOC注解方式的简单使用。下面为AOP简单使用:

    aop的相关术语:

        1 增强(Before、After、Around等)    要额外添加的功能/ 提取出来的重复功能(体现为一个方法)
        2 切面(Aspect)    组织增强的地方 放到代码里就是个类   
        3 连接点(pointcut)  可以添加增强的地方放 spring里就是方法 
        4 切入点  被添加了增强的连接点 
        5 织入    添加增强的过程
        6 目标    要添加增强的地方 

    springAop的开发步骤 :

        1 导包  spring需要额外的aop支持 aspectJ 
        2 编写  切面代码
        3 编写  配置文件 或注解 

    导入依赖后、编写切面以及增强、其实就是编写一个类然后在该类里面编写方法。
    写好后可以直接在增强上添加注解(例如:@Before("execution(* com.*.Student.have*(..))")),或者在配置文件中
    添加:
     

       <aop:aspectj-autoproxy/>  <-- 开启注解方式的Aspect  -->
      	<aop:config>
        	<aop:aspect  ref="aspect2" >
        			<aop:before method="testAspectbefore" pointcut="execution(void com.entity.*.*(..))"/>
        			<aop:after method="testAspectafter" pointcut="execution(void com.entity.*.*(..))"/>
        	</aop:aspect>
        </aop:config>  

    切入点表达式

     execution ( 表达式 )
     表达式 :通配方法: * 代表所有返回值 类的全名一直到方法名(..) 代表所有参数 
     例:execution (* com.oracle.aop.Student.haveClass(..))
    AOP的基本使用就到这里了。在这里在提一个必然会使用的spring声明式事务管理,它是基于AOP技术来实现了。
    声明式事务:基于AOP实现(动态代理方式织入事务、提交/回滚事务),只需要要配置文件中配置好事务规则(tx及aop配置或使用@Transactional注解),注解方式开发简洁推荐使用。

     

     

       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
            <property name="jdbcUrl" value="jdbc:mysql://localhost/test"/>
            <property name="user" value="root"/>
            <property name="password" value="123456"/>
            <property name="maxPoolSize" value="10"/>
            <property name="initialPoolSize" value="2"/>
        </bean>

    在xml中配置一个bean,让spring的事务平台管理类加入到容器中,并提供数据源,这里以c3p0来演示。因使用注解的便利性
    大多数时都是使用@Transactional注解 ,在使用该注解时需要在配置中添加如下:
    <tx:annotation-driven transaction-manager="transactionManager"/>       来开启对事务注解

    关于事务的其他需要了解的:

    事务隔离级别(与数据库四个级别一致)

    1> TransactionDefinition.ISOLATION_DEFAULT    # 这是默认值,表示使用底层数据库的默认隔离级别。大部分数据库通常默认是:READ_COMMITTED读已提交;
    2> TransactionDefinition.ISOLATION_READ_UNCOMMITTED   # 一个事务可以读取另一个事务修改但还没有提交的数据。
         存在问题:该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。
    3> TransactionDefinition.ISOLATION_READ_COMMITTED     # 一个事务只能读取另一个事务已经提交的数据。可以防止脏读,这也是大多数情况下的推荐值。
    4> TransactionDefinition.ISOLATION_REPEATABLE_READ    # 一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。可以防止脏读和不可重复读。
    5> TransactionDefinition.ISOLATION_SERIALIZABLE    # 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,可以防止脏读、不可重复读以及幻读。
         但是这将严重影响程序的性能。通常情况下也不会用到该级别。


    脏读(Dirty read):脏读发生在一个事务读取了被另一个事务改写但还未提交的数据时。如果这些改变在稍后被回滚,那么之前的事务读取的到数据就是无效的。
    不可重复读(Nonrepeatable read):不可重复读发生在一个事务执行相同的查询两次或两次以上,但每一次的查询结果不同时。这通常是由于另一个并发的事务在两次查询之间更新了数据。
    幻读(Phantom read):幻读是一个事务读取几行记录后,另一个事务插入了一些记录,幻读就发生了。在后来的查询中第一个事务就会发现有一些原来没有的额外的记录。

    事务传播行为(TransactionDefinition)

    1> PROPAGATION_MANDATORY # 该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。
    2> PROPAGATION_NESTED    # 如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。 
    3> PROPAGATION_NEVER     # 当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常。
    4> PROPAGATION_NOT_SUPPORTED    # 当前方法不应该运行在一个事务中。如果一个事务正在运行,它将在该方法的运行期间挂起。
    5> PROPAGATION_REQUIRED    # 该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务。
    6> PROPAGATION_REQUIRES_NEW    # 该方法必须运行在自己的事务中。它将启动一个新的事务。如果一个现有的事务正在运行,将在这个方法的运行期间挂起。
    7> PROPAGATION_SUPPORTS    # 当前方法不需要事务处理环境,但如果一个事务已经在运行的话,这个方法也可以在这个事务里运行。
     

  • 相关阅读:
    Kubenetes环境搭建笔记
    Python+Robot Framework实现UDS诊断自动化测试
    Python实现CAN总线J1939报文接收、发送
    [转载]从SQL 2008 复制数据及对像到SQL 2000 的方法
    推荐移动应用:群落(Groupcells)——全球第一款基于图片组的近场社交电子商务平台
    [缓存]迅雷下载原理
    HP大中华区总裁孙振耀退休感言
    [缓存]HTTP协议中的TranferEncoding:chunked编码解析
    [转载]SQL 2008到2005和2000版本的转换
    [学习]SVM入门(一)
  • 原文地址:https://www.cnblogs.com/dingzuoheng/p/12805079.html
Copyright © 2020-2023  润新知