登录后台

页面导航

本文编写于 1064 天前,最后修改于 424 天前,其中某些信息可能已经过时。

spring框架引言

spring第一个环境

spring框架核心思想

![spring框架中的SET注入[4]

spring中构造注入和自动注入

spring工厂特性

代理:proxy

AOP

第一个AOP编程 之 前置通知

AOP编程 之 环绕通知

AOP中切入点表达式

后置通知和异常通知

spring中创建复杂对象

spring框架与mybatis框架整合的思路分析 sm整合

spring整合mybatis 官方

sm 整合步骤

spring整合mybatis的Dao层标准开发

SM标准整合步骤

spring + mybatis 整合 回顾

spring + mybatis service层开发思路分析

spring整合mybatis service层事务控制思路分析(2)

spring 整合 mybatis 最终编程步骤

事务属性

login4j 日志

事务中的一些事务属性

struts2 开发流程

spring 整合 struts2 思路分析

spring整合struts2开发流程

spring + mybatis + struts2 = ssm 整合开发

spring文件中的细节优化

spring注解式开发

ssm注解式开发标准步骤

Spring1

1. Spring框架的引言

spring(春天),生于在2002年,由Rod Johnson创作。Spring框架是一个集众多设计模式于一身的开源的轻量级项目管理框架。致力于JAVAEE轻量级解决方案。相对于原来学过的框架而言,spring框架和之前学习的struts2 、 mybatis 框架有了本质的区别,不是替换原来的某个框架,而是对其进行整合管理

轻量级解决方案:提供一个以简单的、统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。


2.Spring框架的核心作用

Spring 框架用来管理[创建|使用|销毁]项目中的组件,由于spring 框架可以帮我们生产项目中组件对象,因此也习惯称spring是一个工厂|容器

组件: 项目中的service,dao,action,都是项目中的组件

注意: spring框架通常不管理对实体类对象创建


3.第一个环境搭建

a. 引入依赖

  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.2.RELEASE</version>
  </dependency>

b. 引入配置文件

# 配置文件名称: 任意名称 
# 配置文件位置: 项目中根下任意位置
# 配置文件的内容:
        <?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-3.2.xsd ">
    </beans>

c.创建组件

d.工厂管理

<?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.xsd">

      <!--通过bean标签管理组件对象-->
    <bean id="userDAO" class="com.baizhi.dao.UserDAOImpl"></bean>

</beans>

e.启动工厂测试

 public static void main(String[] args) {
             //启动工厂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
                //获取对象
        UserDAO userDAO = (UserDAO) context.getBean("userDAO");

        userDAO.save("小黑");
    }

4.Spring框架中的核心思想

4.1 IOC[控制反转]

  • IOC(inversion of controll)控制反转

    # 1.定义
        将对象的创建由原来(new)的方式转移到配置文件中,交给spring工厂来创建对象
  • DI(dependcy Injection)依赖注入

    # 1.定义
        Spring不仅要创建对象,还要建立类与类之间的关系,因此在控制反转的基础上又提出了依赖注入的概念。

4.2 AOP[面向切面编程]

AOP( Aspect Oriental Programing ) 面向切面的编程


5. SET方式注入

5.1 八种基本类型+String类型 +日期类型的注入

<property name="name" value="zhagnsan"/>
<property name="age" value="21"/>
<property name="id" value="100063"/>
<property name="bir" value="2012/12/12"/>
<property name="price" value="23.23"/>

数组类型注入

<!--注入数组类型数据-->
  <property name="qqs">
     <array>
         <value>xxx</value>
         <value>qqq</value>
         <value>vvvv</value>
      </array>
  </property>

注入引用类型和集合类型

<!--注入引用类型和对象-->
<property name="userDAO" ref="userDAO"/>
<property name="lists">
  <list>
    <value>aaa</value>
    <value>bbb</value>
    <value>ccc</value>
  </list>
</property>
<property name="maps">
  <map>
    <entry key="aa" value="xiaohei"/>
    <entry key="bb" value="xiaoming"/>
    <entry key="cc" value="xiaosan"/>
  </map>
</property>
<property name="props">
  <props>
    <prop key="url">jdbc:mysql://localhost:3306/test</prop>
    <prop key="driver">com.mysql.jdbc.Driver</prop>
    <prop key="username">hr</prop>
    <prop key="password">hr</prop>
  </props>
</property>

**注意**: 引用类型使用ref属性注入,基本类型使用value属性注入


6.构造注入

    <constructor-arg index="0" name="id" value="1"/>
    <constructor-arg index="1" name="name" value="xiaohei"/>
    <constructor-arg index="2" name="age" value="12"/>
    <constructor-arg index="3" name="qqs">
    <array>
      <value>xxx</value>
      <value>222</value>
      <value>333</value>
    </array>
    </constructor-arg>

注意:构造注入并不常用,不过在一些框架类中必须使用构造注入,这里先了解其注入语法即可。

7.自动注入

  • autowire=”byName”

根据注入的属性名与配置文件中bean的id匹配,一致则注入,不一致报错

  • autowire=”byType”

根据注入的属性类型,与配置文件中的类型匹配,类型一致注入(在多个实现类时,会产生歧义)

注意: 无论使用以上那种方式注入都需要为属性提供set方法


8.bean的创建模式

singleton:单例 默认

​ 在工厂中全局唯一,只创建一次

prototype: 多例

全局不唯一,每次使用都会创建一个新的对象

<bean id="" class="xxxx.userAction" scope="prototype|singleton">
        service,dao    ----->  singleton
        struts2 action -----> prototype

注意:在项目开发中service,dao组件单例,struts2的Action必须为:多例


9.bean的生产原理

原理: 反射+构造方法

 UserDAOImpl userDAO = (UserDAOImpl) Class.forName("com.baizhi.dao.UserDAOImpl").newInstance();
 System.out.println(userDAO);

10.bean的生命周期

  • 何时创建

随着工厂启动, 所有单例bean随之创建 非单例的bean,每次使用时创建

  • 何时销毁

工厂关闭,所有bean随之销毁 ( 注意: spring对多例bean管理松散,不会负责多例bean的销毁)

11.bean工厂创建对象的好处

  1. 使用配置文件管理java类,再生产环境中更换类的实现时不需要重新部署,修改文件即可
  2. spring默认使用单例的模式创建bean,减少内存的占用
  3. 通过依赖注入建立了类与类之间的关系(使java之间关系更为清晰,方便了维护与管理)

Spring2

1.现有业务 service 层开发存在问题

a.定义业务接口

public interface UserService {
    void save(String name);
    void delete(String id);
    void update();
    String findAll(String name);
    String findOne(String id);
}

b.实现业务接口

public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void delete(String id) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void update() {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public String findAll(String name) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return name;
    }

    @Override
    public String findOne(String id) {
        try {
            System.out.println("开启事务");
            System.out.println("处理业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return id;
    }
}

问题:从上图中可以看出,现有业务层中控制事务代码出现了大量的冗余,如何解决现有业务层出现的冗余问题?


2.代理引言

a.什么是代理

代理: 指的是java中的一种设计模式

b.为什么需要代理

很多时候除了当前类能够提供的功能外,我们还需要补充一些额外功能。

c.代理的作用

代理对象可以在客户和目标对象之间起到中介作用,从而为目标对象增添额外的功能

d.代理图例


3.静态代理的开发

目标类|对象(target):被代理类称之为目标类|或者被代理的对象的称之为目标对象

    `开发代理的原则: 代理类和目标类功能一致且实现相同的接口,同时代理类中依赖于目标类对象`

a.开发静态代理类

//静态代理类
//开发原则:代理类和目标类实现相同接口,依赖于真正的目标类
public class UserServiceStaticProxy implements UserService {

    //真正的目标类 //target 原始业务逻辑对象
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void save(String name) {
        try {
            System.out.println("开启事务");
            userService.save(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void delete(String id) {
        try {
            System.out.println("开启事务");
            userService.delete(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void update() {
        try {
            System.out.println("开启事务");
            userService.update();//调用真正业务逻辑方法
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public String findAll(String name) {
        try {
            System.out.println("开启事务");
            String result = userService.findAll(name);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return result;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String findOne(String id) {
        try {
            System.out.println("开启事务");
            //调用目标类方法
            String one = userService.findOne(id);//调用真正业务逻辑方法
            System.out.println("提交事务");
            return one;
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
        return null;
    }
}

b.更改目标实现类

public class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void delete(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public void update() {
        System.out.println("处理业务逻辑,调用DAO~~~");
    }

    @Override
    public String findAll(String name) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return name;
    }

    @Override
    public String findOne(String id) {
        System.out.println("处理业务逻辑,调用DAO~~~");
        return id;
    }
}

c.配置静态代理类

        <!--配置目标类-->
    <bean id="userService" class="staticproxy.UserServiceImpl"></bean>

    <!--配置代理类-->
    <bean id="userServiceStaticProxy" class="staticproxy.UserServiceStaticProxy">
        <!--注入目标对象-->
        <property name="userService" ref="userService"/>
    </bean>

d.调用代理方法

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userServiceStaticProxy = (UserService) context.getBean("userServiceStaticProxy");
userServiceStaticProxy.save("小黑");

新的问题:往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢?

解决方案: 为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题 .


4.动态代理的原理

通过jdk提供的Proxy这个类,动态为现有的业务生成代理类

参数一:当前线程类加载器
参数二:生成代理类的接口类型
参数三:通过代理类对象调用方法时会优先进入参数三中的invoke方Proxy.newProxyInstance(loader, interfaces, h);//返回值就是动态代理对象
public class TestDynamicProxy {
    public static void main(String[] args) {
        final UserService userService =  new UserServiceImpl();
        //参数1:当前线程类加载器
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        //参数2:
        Class[] classes =  new Class[]{UserService.class};
        //参数3:
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(contextClassLoader, classes, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try{
                    System.out.println("开启事务");//附加操作
                    Object invoke = method.invoke(userService, args);
                    System.out.println("提交事务");//附加操作
                    return invoke;
                }catch (Exception e){
                    System.out.println("回滚事务");//附加操作
                }
                return null;
            }
        });
        userServiceProxy.save("小黑");
    }
}

5.AOP (Aspect Oriented Programming)编程

通知(Advice): 除了目标方法以外的操作都称之为通知

    `切入点(PointCut): 要为哪些类中的哪些方法加入通知`
    `切面(Aspect)`: `通知 + 切入点`

1.通知分类

2.编程步骤

# 1.引入依赖
     spring-aop
     spring-expression
     spring-aspects

# 2.开发通知类
      MethodBeforeAdvice      前置通知
      MethodInterceptor       环绕通知
      AfterReturningAdvice    返回后通知
      ThrowsAdvice                        异常通知
      
      MyAdvice implements  通知接口{.....}
      
    //自定义通知类:用来完成额外功能
    public class MyAdvice  implements MethodBeforeAdvice {
        @Override//参数1:当前调用的方法对象    //参数2:当前调用方法对象的参数  //参数3:
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("目标方法名: "+method.getName());
            System.out.println("目标方法的参数: "+objects);
            System.out.println("目标对象: "+o.getClass());
        }
    }
# 3.配置切面
        a.引入aop命名空间
              <?xml version="1.0" encoding="UTF-8"?>
             <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
                                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
        b.管理通知
             <!--管理通知类-->
         <bean id="myAdvice" class="before.MyAdvice"/>
       c.配置切面
           <aop:config>
        <aop:pointcut id="pc" expression="execution(* before.UserServiceImpl.*(..))"/>
        <aop:advisor advice-ref="myAdvice" pointcut-ref="pc"/>
        </aop:config>

# 4.启动工厂测试
                 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("before/spring.xml");
        UserService userSerivce = (UserService) context.getBean("userService");
        System.out.println(userSerivce.getClass());
        userSerivce.save("小黑");

3.前置通知的使用

4.环绕通知的使用

5.返回后通知

6.异常通知


6.切入点表达表

1.execution方法级别的切入点表达式

注意:方法级别的切入点表达式尽可能精准,否则程序运行可能出现异常

2.within类级别的切入点表达式

# 1.语法
    within(包.类)

# 2.示例
    within(com.baizhi.service.*) 
            包: com.baizhi.service
            类: 所有类中所有方法不关心返回值和参数
    
    within(com.baizhi.service.UserServiceImpl)
            包: com.baizhi.service
            类: UserServiceImpl类中所有方法不关心返回值和参数

注意:within的效率高于execution表达式,推荐使用within表达式

Spring3

1.创建复杂对象

复杂对象: 类中没有构造方法,或者构造方法不能调用如接口类型或抽象类实例

//1.类 implements FactoryBean<创建的类型>

    public class ConnectionFactoryBean implements FactoryBean<Connection> {
    @Override
    public Connection getObject() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
    }

// 2.配置工厂管理
        <bean id="connectionFactoryBean" class="com.baizhi.factorybean.ConnectionFactoryBean"></bean>

// 3.获取复杂对象
            ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Connection conn = (Connection) context.getBean("connectionFactoryBean");
        System.out.println(conn);

2.SM整合思路

1.spring框架的作用

spring框架 项目管理框架 主要负责项目中组件对象的创建

2.Mybatis框架的作用

Mybatis框架 持久层框架 主要用来简化数据库访问的操作

3.整合思路

整合思路: 两个框架作用不同,貌似没有什么联系,更深入看才能看出所谓Spring整合Mybatis,其实就是通过spring框架接管mybatis框架中核心对象的创建

4.mybatis中的核心对象有哪些

Mybatis的核心对象为: SqlSessionFactory 整合就是通过Spring管理SqlSessionFactory对象的创建

5.整合思路图示

2.SM整合DAO编程步骤

1.引入mybatis的依赖jar包

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.2.8</version>
</dependency>

2.引入Spring相关jar包

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.2.RELEASE</version>
  </dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>

3.mybatis-spring整合jar

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.3.1</version>
</dependency>

4.引入数据库驱动jar

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.40</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>

5.建表

CREATE TABLE `t_user` (
  `id` varchar(40) NOT NULL,
  `name` varchar(40) DEFAULT NULL,
  `age` int(3) DEFAULT NULL,
  `bir` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

6.编写实体类

public class User {
    private String id;
    private String name;
    private Integer age;
    private Date bir;
        //......
}

7.书写DAO接口

public interface UserDAO {
    //查询所有
    List<User> findAll();
}

8.编写mapper配置文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baizhi.dao.UserDAO">
    
    <select id="findAll" resultType="com.baizhi.entity.User">
        select id,name,age,bir from t_user
    </select>

</mapper>

9.编写Spring-myabtis整合配置文件

        <!--创建数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/sm"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--创建sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" >
            <array>
                <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
            </array>
        </property>
    </bean>

    <!--创建DAO-->
    <bean id="userDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        <property name="mapperInterface" value="com.baizhi.dao.UserDAO"/>
    </bean>

10.启动工厂测试

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserDAO userDAO = (UserDAO) context.getBean("userDAO");
List<User> users = userDAO.findAll();
for (User user : users) {
  System.out.println(user);
}

3.SM整合Service编程步骤

1.编写spring-mybatis.xml配置文件

<!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置事务属性-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
            <tx:method name="find*"/>
        </tx:attributes>
    </tx:advice>

    <!--配置事务切面-->
    <aop:config>
        <aop:pointcut id="pc" expression="within(com.baizhi.service.*)"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    </aop:config>

2.配置图示

3.创建service接口

public interface UserService {
    List<User> findAll();
}

4.创建service对象

public class UserServiceImpl implements UserService {
    
    private UserDAO userDAO;
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public List<User> findAll() {
        return userDAO.findAll();
    }
}

5.配置业务组件对象

  <!--配置Service组件-->
    <bean id="userService" class="com.baizhi.service.UserServiceImpl">
        <property name="userDAO" ref="userDAO"/>
    </bean>

6.启动测试


4.事务属性

1.事务传播属性

# propagation: 传播
        
        REQUIRED:            需要事务,外部存在事务融入当前事务,外部没有事务,开启新的事务
        SUPPORTS:            支持事务,外部存在事务融入当前事务,外部没有事务,不开启新的事务
        REQUIRES_NEW:        每次开启新的事务,如果外部存在事务外部事务挂起,开启新的事务运行,运行结束后回复外部事务
        NOT_SUPPORTED:       不支持事务,如果外部存在事务外部事务挂起,已非事务方式运行.
        NEVER:                 不支持事务,存在事务报错
        MANDATORY:             强制事务没有事务报错
        NESTED:                 嵌套事务,数据库不支持

2.事务的隔离级别

# isolation 隔离级别
    
    DEFAULT:             采用数据库默认隔离级别
    READ_UNCOMMITTED:     读未提交 
    READ_COMMITTED:     读提交 用来避免脏读现象出现的   oracle默认隔离级别
    REPEATABLE_READ:     可重复读主要是用来避免不可重复读现象出现的 (在一次事务中一方更新,导致两次查询结果不一致这种情况叫不可重复读)  mysql默认隔离级别
    SERIALIZABLE   :     序列化读 用来避免幻影读现象出现          (在一次事务中一方插入,导致两次查询结果不一致这种情况叫幻影读)
    

3.读写和异常性

# readonly 
   `true:    本次事务只读
   `false:   本次事务非只读
    <tx:method name="save*" propagation="REQUIRES_NEW" read-only="true|false" isolation="SERIALIZABLE"/>
    
# rollback-for && no-rollback-for=""
        rollback-for: 遇到什么类异常回滚
        no-rollback-for: 遇到什么类异常不回滚
       <tx:method name="save*" rollback-for="" no-rollback-for="" propagation="REQUIRES_NEW" read-only="true" isolation="SERIALIZABLE"/>

# timeout 超时性
        timeout: -1 永不超时

Spring4

1.Spring整合Struts2框架

1.引入依赖

需要引入: struts2 Spring Struts2-Spring-plugin


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

2.配置web.xml

  1. 配置struts2核心控制器
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  1. 配置spring启动工厂
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  1. 加载工厂配置文件
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>

3.开发Action

public class UserAction {
    public String findAll(){
        System.out.println("hello action~~ ");
        return Action.SUCCESS;
    }
}

4.工厂管理Action组件

  <!--管理Action-->
  <bean id="userAction" class="com.baizhi.action.UserAction"></bean>

5.配置struts.xml

<package name="user" extends="struts-default" namespace="/user">
  <action name="findAll"  class="userAction" method="findAll">
    <result name="success">/index.jsp</result>
  </action>
</package>

注意:`配置文件中书写的是工厂中管理的action的bean的id`

6.部署项目测试


2.Spring的注解式开发

注解: Annotation

注解开发: 为了去提高现有配置文件开发的开发效率

1.开启注解扫描配置

<!--开启注解扫描-->
<context:component-scan base-package="com"/>

2.实例化相关注解

Spring自2.5版本以后提供了一些注解用来在使用spring时进行快速开发

# 1. @Component(value="beanid")
                修饰范围:    用在类上
                注解作用:    通用的创建实例的注解,用来创建当前这个类的实例
                value属性:    用来指定创建的对象在工厂中的唯一标识   如果不指定默认创建对象在工厂中的标识为类名首字母小写
                
# 2. @Repository 
                修饰范围:    用在类上
                注解作用:    @component的子类注解专用于DAO组件的创建,通常加在DAO组件上
                value属性:    用来指定创建的对象在工厂中的唯一标识   如果不指定默认创建对象在工厂中的标识为类名首字母小写

# 3. @Service
                修饰范围:    用在类上
                注解作用:    @component的子类注解专用于Service组件的创建,通常加在Service组件上
                value属性:    用来指定创建的对象在工厂中的唯一标识   如果不指定默认创建对象在工厂中的标识为类名首字母小写

# 4. @Controller
              修饰范围:    用在类上
                注解作用:    @component的子类注解专用于Action组件的创建,通常加在Action组件上
                value属性:    用来指定创建的对象在工厂中的唯一标识   如果不指定默认创建对象在工厂中的标识为类名首字母小写

3.控制对象的创建次数的注解

 # 1. @Scope(value="singleton|prototype")
               修饰范围:    用在类上
                注解作用:    用来控制这个实例在工厂中的创建次数
                value属性:    singleton为单例,prototype为多例   默认单例

4.注入相关的注解

# 1. @Autowired(Spring提供)
                修饰范围:    用在成员变量或成员变量的GET/SET方法上
                注解作用:         用来给类中成员变量赋值
                注入原则:    默认根据类型自动注入

# 2. @Resource(JAVAEE提供)
                修饰范围:    用在成员变量或成员变量的GET/SET方法上
                注解作用:         用来给类中成员变量赋值
                注入原则:    默认根据名称自动注入名称找不到根据类型自动注入

5.控制事务的相关注解

# 1. @Transactional
              修饰范围:    用在类上主要用在业务层组件类上或者是方法上
                注解作用:         用来给类中方法加入事务,当类上和方法上同时存在该注解时局部优先
                注解属性:    
                            propagation  用来控制传播属性
                            Isolation    用来控制隔离级别
                            timeout      用来设置超时性
                            rollback-for 用来设置什么异常回滚
                            norollback-for 用来设置什么异常不会滚
                            readonly     用来设置事务读写性

注意:如果要使用事务注解在配置文件中必须开启事务注解生效加入如下配置:

    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
博主已关闭本页面的评论功能