简单使用spring

什么是Spring

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的三层架构[表现层(Controller层)、业务逻辑层(Service层)、数据访问层(DAO层)]中,每一层均提供了不同的解决技术

spring三层

  1. 表现层(Controller层):Spring MVC
  2. 业务逻辑层(Service层):Spring的IoC
  3. 数据访问层(DAO层):支持mybaits,hibernate,封装jdbc

Spring 的优势

  1. 低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
  2. 声明式事务管理(基于切面和惯例)
  3. 方便集成其他框架(如MyBatis、Hibernate)
  4. 降低 Java 开发难度
  5. Spring 框架中包括了 J2EE 三层的每一层的解决方案

spring的核心

  1. IOC:(Inverse of Control 控制反转):将对象的创建权,交由Spring完成
    1. DI:依赖注入:依赖注入可以说是控制反转的一个具体实现例子,其在Spring中的体现在于组件之间的依赖关系由容器控制,我们通过简单的配置,不通过代码就可以得到指定的资源。
  2. AOP : Aspect Oriented Programming 是 面向对象的功能延伸.不是替换面向对象,是用来解决OO中一些问题

spring IoC

控制反转 ,也叫依赖注入,是面向对象编程中的一种设计理念,用来降低程序代码之间的耦合度。将创建对象的权力交给容器。

使用的步骤

1. 通过maven导入spring核心jar

<!--spring start-->
    <!-- spring-beans -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

    <!--spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

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

    <!-- spring-expression -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

    <!-- commons-logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

    <!--spring end-->

2. 创建配置文件 spring-config.xml

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 定义第一个Bean实例:bean1 -->
     <bean id="..." class="...">
        
    </bean>

</beans>
  1. spring-config.xml的元素
    1. beans

      beans元素是Spring配置文件的根元素

    2. bean

      bean元素是Spring配置文件的beans元素的子元素,beans元素可以包含多个bean子元素,每个bean元素相当于定义了一个实例,相当于容器创建了一个对象;定义bean时通常需要指定两个属性

      • id:确定该Bean的唯一标识符,容器对Bean管理、访问、以及该Bean的依赖关系,都通过该属性完成。 Bean的id属性在Spring容器中是唯一的。
      • class:指定该Bean的具体实现类。注意这里不能使接口。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的类名。
  2. 创建一个bean
    1. 创建一个bean类

      package cn.pojo;
      
      import java.io.Serializable;
      import java.util.Date;
      
      public class News implements Serializable{
      	private Integer id;//ID
      	private String title;//标题
      	private String content;//内容
      	private Date createTime;//创建时间
          
          public News() {}
      
      	public Integer getId() {
      		return id;
      	}
      
      	public void setId(Integer id) {
      		this.id = id;
      	}
      
      	public String getTitle() {
      		return title;
      	}
      
      	public void setTitle(String title) {
      		this.title = title;
      	}
      
      	public String getContent() {
      		return content;
      	}
      
      	public void setContent(String content) {
      		this.content = content;
      	}
      
      	public Date getCreateTime() {
      		return createTime;
      	}
      
      	public void setCreateTime(Date createTime) {
      		this.createTime = createTime;
      	}
      }
      
      
    2. 配置spring-config.xml文件

      • 当我们在配置文件中通过方法配置一个Bean时,这样就需要该Bean实现类中必须有一个无参构造器。
      <?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
              https://www.springframework.org/schema/beans/spring-beans.xsd">
           <bean id="news" class="cn.pojo.News"></bean>
      </beans>
      
      • 在配置的时候我们还可以给这个Bean类中的属性赋值,通过bean的子元素property实现spring中的setter注入方式
      <bean id="news" class="cn.pojo.News">
          <!-- 给名字为id的属性赋值 1 -->
           <!--(将nama中的值的前面加上set,然后将首字母变为大写 变成setId,从而找到id的set方法来给id赋值) -->
          <property name="id" value="1"/>
          <!-- 可通过ref 引入其余的bean 给对象属性赋值 -->
          <property name="属性名" ref="bean"/>
      </bean>
      

      多种方式实现依赖注入

      1. 构造注入:

        ​ 使用构造函数注入:添加构造函数(前提是这个构造函数存在)

        //在News类中添加id的构造函数
        public News(Integer id) {
        		this.id = id;
        	}
        
         <!-- 使用构造函数配置 -->
        <bean id="news" class="cn.pojo.News">
            <!-- 给构造函数的第一个参数赋值 1 -->
            <constructor-arg><value>345</value></constructor-arg>
            <!-- 也可以是通过index指定给构造函数的第几个参数赋值 1 -->
            <constructor-arg index='1'><value>345</value></constructor-arg>
        </bean>
        

        给构造函数的参数赋值的顺序是根据前后顺序来的,也可通过参数index指定

      2. p命名空间注入

        ​ 先配置xml文件的beans的属性

         <!-- 加在beans元素上 -->
        xmlns:p="http://www.springframework.org/schema/p"
        
        <bean id="news" class="cn.pojo.News" p:id='1'></bean>
        
      3. 注入特殊符号
        使用<![CDATA[值]]>:将值里的特殊字符转换成纯文字

3. 测试

public class TestNews {
    
	@Test
	public void test01()
	{
		//1.获取spring配置文件
		 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		 //2.由配置文件返回对象,使用getBean方法指定id获取
		 News news = (News)context.getBean("news");
		 System.out.println(news.getId());
	}
}

通过注解实现IoC的配置

1. 在Bean类上定义注解

package cn.biz.impl;


import cn.biz.OrderBiz;
import cn.mapper.order.OrderDetailMapper;
import cn.mapper.order.OrderMapper;
import cn.pojo.Order;
import cn.pojo.OrderDetail;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("orderBiz")
public class OrderBizImpl implements OrderBiz {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public Integer add(Order order, OrderDetail orderDetail) throws Exception {
        orderMapper.add(order);
        orderDetail.setOrderId(order.getId());
        return orderDetailMapper.add(orderDetail);
    }

    public OrderMapper getOrderMapper() {
        return orderMapper;
    }

    public void setOrderMapper(OrderMapper orderMapper) {
        this.orderMapper = orderMapper;
    }

}



@Component是定义任意层的注解

而Spring提供了三个特殊的注解

  1. @Repository:用于标注Dao类
  2. @Service:用于标注业务类
  3. @Controller:用于标注控制器类

使用这些注解来定义,将相当于在spring中定义了一个

<bean id="orderController" class="cn.Controller.OrderController"></bean>

注解后面的括号是用于指定bean的id

2. 配置spring-config.xml,扫描这些注解

  1. 首先将添加beans的context

  2. 定义扫描注解的范围

    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 指定扫描的范围 -->
    	<context:component-scan base-package="cn.biz,cn.aop,cn.controller"/>
    </beans>
    

3. 使用注解实现Bean组件的装配

  1. spring注解完成装配
    spring提供了@Autowired注解实现Bean的装配
    若容器中有一个以上的类型相匹配的Bean时,则可以使用 @Qualifier()指定所需要的Bean名称

    package cn.controller;
    
    import cn.biz.OrderBiz;
    import cn.pojo.Order;
    import cn.pojo.OrderDetail;
    import org.omg.CORBA.INTERNAL;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    import java.util.List;
    
    /**
     * 作者:weisen
     * 日期:2019/9/27 19:24
     */
    @Controller("orderController")
    public class OrderController {
    
        @Autowired
        @Qualifier("orderBiz")
        private OrderBiz orderBiz;
    
        public List<Order> getOrderList(Integer userId){
            return orderBiz.getOrderList(userId);
        }
    }
    
    
  2. 使用Java标准注解完成装配
    @Resource(name = “”)
    @Resource的name属性,默认情况下,Spring将这个属性的值解释为要注入的Bean的名称

    package cn.controller;
    
    import cn.biz.OrderBiz;
    import cn.pojo.Order;
    import cn.pojo.OrderDetail;
    import org.omg.CORBA.INTERNAL;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    import java.util.List;
    
    /**
     * 作者:weisen
     * 日期:2019/9/27 19:24
     */
    @Controller("orderController")
    public class OrderController {
    
        @Resource(name = "orderBiz")
        private OrderBiz orderBiz;
    
        public List<Order> getOrderList(Integer userId){
            return orderBiz.getOrderList(userId);
        }
    }
    
    

4. 测试

public class Test {
    
	@Test
	public void test01()
	{
		//1.获取spring配置文件
		 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		 //2.由配置文件返回对象,使用getBean方法指定id获取
		 OrderController news = (OrderController)context.getBean("orderController");
		
	}
}

Spring AOP

什么是AOP

AOP 即 Aspect Oriented Program 面向切面编程 是一种面向切面编程的编程思路 但是spring AOP只是AOP的一种简化版

spring AOP 的目的

将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性

spring AOP 当中的概念:

  • 切面(Aspect)
    切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!
  • 连接点(Join Point):程序执行中的某个具体的执行点。
  • 增强处理(Advice):切面在某个特定的连接点上执行的代码逻辑。
  • 切入点(Pointcut)
    在哪些类,哪些方法上切入(where
  • 织入(Weaving)
    把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)

使用spring AOP的步骤

1. 导入jar

<!--spring-aop start-->
    <!--aspectj weaver-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>

    <!-- spring-aop -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

    <!--aopalliance -->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>
<!--spring-aop end-->

2.定义切面

创建类定义切面

public class beforeLogger {
    private Logger log  = Logger.getLogger(beforeLogger.class);
    //定义切面
    public void brfore(){
        log.info("方法执行之前");
    }
}

3. 配置spring-config.xml文件

<!--定义切面的Bean-->
<bean id="beforeLogger" class="aop.beforeLogger"></bean>
<!--配置切入信息-->
<aop:config>
    <!--定义切入点-->
      <aop:pointcut id="pointcut" expression="execution(* service.UserServiceImpl.*(..))"/>
      <aop:aspect ref="beforeLogger">
      <!--织入-->
          <!--前置增强-->
          <!--在执行方法之前会执行 brfore()方法-->
          <aop:before method="brfore" pointcut-ref="pointcut" throwing="e"></aop:before>
          <!--后置增强:在执行方法(正常执行完成后)后调用 
				returning 指定为名为result的参数注入返回值-->
          <aop:after-returning method="afterReturning"
                pointcut-ref="pointcut" returning="result">
          </aop:after-returning>
          <!--后置增强:在执行方法(正常执行完成后)后调用 
				returning 指定为名为result的参数注入返回值-->
          <aop:after-returning method="afterReturning"
                pointcut-ref="pointcut" returning="result">
          </aop:after-returning>
          <!--  异常抛出增强:执行方法异常时执行
				throwing 指定为名为e的异常注入返回值-->
           <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" 				 			throwing="e">
          </aop:after-throwing>
          <!--  最终增强:无论方法时正常还是异常退出都会执行
				returning 指定为名为result的参数注入返回值-->
          <aop:after method="afterReturning"
                pointcut-ref="pointcut" returning="result"></aop:after>
      </aop:aspect>
</aop:config>

除了之前的单个功能的增强,还有一种包含了多数的增强的 环绕增强

  1. 定义环绕增强切面
public class ArroundLogger {
    private static final Logger log = Logger.getLogger(ArroundLogger.class);
    public Object arroundLogger(ProceedingJoinPoint jp) throws Throwable {
        log.info("调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。方法入参" + Arrays.toString(jp.getArgs()));
        try {
            Object result = jp.proceed();
            log.info("调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。方法返回值" + result);
            return result;
        } catch (Throwable e) {
            log.error(jp.getSignature().getName() + "方法发生异常:" + e);
            e.printStackTrace();
            throw e;
        } finally {
            log.info(jp.getSignature().getName() + "方法结束执行");
        }
    }
}
  1. 使用环绕增强

    <aop:around method="arroundLogger" pointcut-ref="pointcut"></aop:around>
    

通过注解使用AOP

1. 定义注解

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.Aspect;
//使用 @Aspect 注解将beforeLogger定义为切面
@Aspect
public class beforeLogger {
    
    private Logger log  = Logger.getLogger(beforeLogger.class);
    
    
    //前置增强注解
    @Before("execution(* action.UserAction.*(..))")
    public void brfore(){
        log.info("方法执行之前");
    }
    
    //最终增强注解
     @After("execution(* action.UserAction.*(..))")
    public void afterLogger(JoinPoint jp){
        log.info(jp.getSignature().getName()+"方法结束执行");
    }
    
    //后置增强注解
     @AfterThrowing(pointcut = "execution(* action.UserAction.*(..))",throwing = "e")
    public void afterThrowing(JoinPoint jp,RuntimeException e){
        log.error(jp.getSignature().getName()+"犯法发生异常:"+e);
    }
    
    //环绕增强注解
     @Around("execution(* action.UserAction.*(..))")
    public Object arroundLogger(ProceedingJoinPoint jp) throws Throwable {
        log.info("调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。方法入参" + Arrays.toString(jp.getArgs()));
        try {
            Object result = jp.proceed();
            log.info("调用" + jp.getTarget() + "的" + jp.getSignature().getName() + "方法。方法返回值" + result);
            return result;
        } catch (Throwable e) {
            log.error(jp.getSignature().getName() + "方法发生异常:" + e);
            e.printStackTrace();
            throw e;
        } finally {
            log.info(jp.getSignature().getName() + "方法结束执行");
        }
    }
    
    //定义切入点
 	@Pointcut("execution(* action.UserAction.*(..))")
 	public void pointcut(){}
    
    //通过引用定义的切入点,使用增强
     @AfterReturning(pointcut = "pointcut()",returning = "result")
   	 public void afterReturning01(JoinPoint jp,Object result){
        log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法入参:"+result);
    }
}

2. 配置xml文件 ,扫描注解,并且启动AOP注解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
   <!-- 扫描注解 -->
 <context:component-scan base-package="cn.biz"></context:component-scan>
    <!-- 启动AOP注解 -->
     <aop:aspectj-autoproxy/>
 </beans>

spring-mybatis整合

整合的步骤

1. 导入相关的jar

  1. mybatis

        <!--mybatis start-->
        <!--mysql  jar-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.17</version>
        </dependency>
    
        <!-- mybatis -->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.2</version>
        </dependency>
    
        <!--log4j-->
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
        </dependency>
        <!--mybatis end-->
    
  2. spring

    <!--spring start-->
        <!-- spring-beans -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
          <version>5.1.9.RELEASE</version>
        </dependency>
    
        <!--spring-core -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>5.1.9.RELEASE</version>
        </dependency>
    
        <!-- spring-context -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.1.9.RELEASE</version>
        </dependency>
    
        <!-- spring-expression -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-expression</artifactId>
          <version>5.1.9.RELEASE</version>
        </dependency>
    
        <!-- commons-logging -->
        <dependency>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
          <version>1.2</version>
        </dependency>
    
        <!--spring end-->
    
  3. 数据源

       <!-- commons-dbcp2 -->
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-dbcp2</artifactId>
          <version>2.7.0</version>
        </dependency>
    
        <!-- commons-pool2 -->
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-pool2</artifactId>
          <version>2.7.0</version>
        </dependency>
    
  4. spring-mybatis

    <!--spring-mybatis end-->
    <!-- mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.1</version>
    </dependency>
    <!-- spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <!-- spring-tx -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <!--spring-mybatis end-->
    

2. 配置mybatis-config.xml文件

由于数据源的配置移入了spring中,所以mybatis-config.xml的文件变得很简约

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="logImpl" value="LOG4J"></setting>
    </settings>

    <typeAliases>
        <package name="cn.pojo"/>
    </typeAliases>
</configuration>

3. 配置spring-config.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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
	<!-- 内部配置数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url">
            <value><![CDATA[jdbc:mysql://127.0.0.1:3306/easybuy?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8]]></value>
        </property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!--定义工厂-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:myBatis-config.xml"/>
    </bean>

    <!-- 将mapper里的映射文件,全部通过工厂创建好bean 创建好的bean id命名就是类名首字母改成小写 -->
    <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.mapper" />
    </bean>
    <!--单个单个类的扫描 -->
    <!--<bean id="classesMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="mapper.classes.ClassesMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>-->
    <!-- 根据已存在的mappper的bean 定义biz层的bean -->
    <bean id="classesService" class="service.impl.ClassesServiceImpl">
       <property name="classesMapper" ref="classesMapper"></property>
    </bean>
</beans>

4. 测试

@Test
public  void testRole(){
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    对象类型 对象名 = (对象类型)context.getBean("bean的id");
    对象名.方法();
}

事务

1. 导入jar

由于在配置spring-mybatis和aop的时候就已经将jar导入,这里就不用导入jar了

2. 配置声明式事务

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

    
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url">
            <value><![CDATA[jdbc:mysql://127.0.0.1:3306/easybuy?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8]]></value>
        </property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    
    <!--定义切面-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--设置事件的属性-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
             <!--tx:method可以有多个 name是必须的 用于指定匹配的方法-->
            <tx:method name="add" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 定义切面 -->
    <aop:config>
        <!--定义切点-->
        <aop:pointcut id="pointCut" expression="execution(* cn.biz..*.*(..))"/>
        <!--将事务增强-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"></aop:advisor>
    </aop:config>
</beans>

Propagation支持7种不同的传播机制:

REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。

SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。

REQUIRESNEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常

NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。

3. 通过注解定义事务

  1. 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/tx
            https://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <context:component-scan base-package="cn.biz,cn.aop,cn.controller"/>
    
        <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
            <property name="url">
                <value><![CDATA[jdbc:mysql://127.0.0.1:3306/easybuy?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8]]></value>
            </property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
    
        <!--定义切面-->
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    	
        <!-- 启用事务注解 -->
        <tx:annotation-driven transaction-manager="txManager"/>
    </beans>
    
  2. 使用事务注解

    	@Transactional(propagation = Propagation.REQUIRED)
        public Integer add(Order order, OrderDetail orderDetail) throws Exception {
            orderMapper.add(order);
            orderDetail.setOrderId(order.getId());
            return orderDetailMapper.add(orderDetail);
        }
    

    此方法就添加了事务增强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值