栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring基础笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring基础笔记

文章目录
        • 什么是Spring框架?
        • Spring框架的作用是什么?
        • Spring框架的优点?
        • 组成Spring框架的七大模块是什么?
        • Spring框架核心技术,IOC思想是什么?
        • Spring常用配置有哪些?
        • Spring如何进行依赖注入?
        • Bean的作用域是什么?
        • 什么是Bean的自动装配?
        • 如何使用注解实现自动装配?@Autowired与@Resource的区别?
        • 如何使用注解开发?Spring常用注解有哪些?
        • 如何使用Java方式配置Spring?
        • Spring中的代理模式是什么?有哪些?
        • Spring框架核心技术,AOP思想是什么?
        • AOP在Spring中的作用是什么?
        • Spring如何实现AOP?
        • Spring的声明式事务管理是什么?

什么是Spring框架?

Spring是轻量级的IOC和AOP的容器框架,主要是针对Bean的生命周期进行管理的轻量级容器。

Spring框架的作用是什么?

Spring框架主要用来帮助我们管理当前项目的组件对象,核心组件对象不需要在关注创建了。

Spring框架的优点?
  1. 轻量级:Spring框架运行占用资源少,运行效率高。
  2. 针对接口编程,解耦合:Spring提供了IOC控制反转,由容器管理对象之间的依赖关系。
  3. AOP编程的支持:不容易用传统的OOP实现的功能可以通过Spring提供的AOP实现。
  4. 方便集成各种优秀框架:Spring降低了框架的使用难度,并且提供了对各种优秀框架的直接支持(Struts Hibernate Mybatis)简化框架的使用,可以需要哪个就集成那个,不需要就移除。
组成Spring框架的七大模块是什么?

Spring构建在核心容器Spring Core之上,核心容器定义了创建,配置和管理Bean的方式。

  1. Spring Core:核心容器。
    提供依赖注入来实现容器对Bean的管理,核心容器的主要组件是工厂模式的一个实现BeanFactory,它是Spring应用的核心。通过IOC将应用配置和依赖从实际的应用代码中分离出来。
  2. Spring AOP:面向切面编程模块。
    提供面向切面编程的丰富支持,Spring AOP对基于Spring应用程序中的对象提供了事务管理。通过使用Spring AOP不用依赖组件,就可以将声明性事务管理集成到应用程序中。
  3. Spring Web MVC:MVC模块。
    Spring为构建Web应用提供了全功能的MVC框架,SpringMVC框架使用IOC对控制逻辑和业务对象进行了完全分离。
  4. Spring ORM:对象关系映射模块。
    Spring ORM提供了对ORM框架的支持,可以进行集成其它ORM框架,方便以面向对象的思想实现数据库的操作。
  5. Spring Web:Web模块。
    扩展了Spring上下文,提供Web应用上下文,对Web开发提供了功能上的支持(比如请求,表单,异常等)。
  6. Spring DAO:JDBC/DAO模块。
    提供了一个JDBC的抽象层和异常层次结构,解除了繁琐的JDBC编码和数据库厂商特有的错误代码解析,用于简化JDBC。
  7. Spring Context:应用上下文模块。
    Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。事件处理,国际化等功能。它还提供了一些企业级服务JNDI,EJB,RMI的支持。
Spring框架核心技术,IOC思想是什么?
  1. IOC控制反转:
    控制反转不是一种技术而是一种思想,是指将对象的生命周期管理过程,交给Spring容器进行管理,转移了对象的控制权,由容器控制程序之间的依赖关系。

  2. DI依赖注入:
    依赖注入是实现控制反转的方式,是指容器在创建对象的过程中根据对象之间的依赖关系,将不同的对象注入到不同的属性中。

  3. IOC与DI的关系:
    DI本质上是对IOC思想的一种补充,如果说IOC更像是一个抽象的概念的话,那么DI就是具体实现了。

  4. BeanFactory接口:Bean的工厂接口。

    IOC容器的基本实现,所有的容器必须实现BeanFactory接口。它是Spring框架的基础,面向Spring本身。

  5. ApplicationContext接口:

    继承于BeanFactory,面向Spring的使用者。

    常用方法:

    • getBean(String name):根据id获取容器中的Bean。
    • getBean(Class):根据类型获取容器中的Bean,要求容器中的Bean只能是单例。
    • getBean(String name, Class aClass):根据id的基础上再根据类型获取Bean。

    常见实现类:

    • ClassPathXmlApplicationContext:配置文件在类路径下(src)。
    • FileSystemXmlApplicationContext:配置文件在文件系统中。
    • AnnotationConfigApplicationContext:配置文件是Java配置类。
Spring常用配置有哪些?
  • Bean的配置:

    • id:Bean的唯一标识符,也可以说是Bean的名字。

    • class:Bean对象所对应的全限定类名。

    • name:声明别名,以逗号分隔可以声明多个别名(扩展一下其实分号也能分隔,Spring兼容了能想到的所有分隔符)。

    • ref:给一个对象的属性设置值,引用其它Bean id。

      
      
          
          
          
          
              	
      			
      	
      
      
      
          
      
      
    • List集合:

      
          
          
          
      
      
    • Set集合:

      
          
          
          
      
      
    • Map集合:

      
          
          
      
      
    • 数组:

      
          
          
                 
      
      
    • 空值:

      
      
  • 别名:

    
        
        
        
    
    
    
    
    
  • import:多数用于团队开发,将多个配置文件导入到一个配置文件中。

    • Java导入多个配置文件:

      //在Java类主函数中new ClassPathXmlApplicationContext有参构造器导入多个配置文件
      ApplicationContext c = new ClassPathXmlApplicationContext(
                      "spring-config1.xml","spring-config2.xml");
      
    • 通过import导入多配置文件(团队开发推荐):

      
      
      
      
      //有参构造器中导入总配置文件
      ApplicationContext c = new ClassPathXmlApplicationContext(
                      "application-context.xml");
      
Spring如何进行依赖注入?
  • 构造器注入:要求Bean提供一个有参构造器。

    • 下标赋值:

      
      
          
          
          
      
      
    • 类型赋值(不推荐):

      
      
           
           
           
      
      
    • 参数名赋值:

      
      
          
          
          
      
      
  • Set方式注入:要求Bean提供一个无参构造器,和对应的Setter方法。

    
        
        
        
    
    
  • 属性注入:属性注入用于注解方式。

  • (扩展)P命名空间和C命名空间:

    
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    
    
    
    
    
    
Bean的作用域是什么?

scope属性/scope注解:指定Bean的作用域。

  • singleton:单例模式。
    • 使用该属性定义Bean,容器只创建一个Bean实例,容器每次返回的是同一个Bean实例。
  • prototype:原型模式。
    • 使用该属性定义Bean,容器创建多个Bean实例,容器每次返回的都是一个新的实例。
  • request:HTTP请求。
    • 该属性仅对HTTP请求产生作用,使用该属性定义Bean,每次HTTP请求都会创建一个新的Bean。
  • session:会话。
    • 该属性仅用于HTTP Session,同一个Session共享一个Bean实例,不同的Session使用不同的实例。
  • global session:全局会话(Spring5.X中已删除)。
    • 该属性仅用于HTTP Session,所有的Session共享一个Bean实例。
什么是Bean的自动装配?

Spring中有三种装配方式:

  1. 在XML中显示装配:

    
        
        
        
        
    			
    	
    
    
    
        
    
    
  2. 在Java中显示装配:

    //这个类也会被Spring容器托管,注册到容器中,因为它自身就是一个@Component,
    //@Configuration代表这是一个配置类,就和我们之前看的beans.xml一样
    @Configuration
    public class Config {
    
        //注册一个bean,就相当于我们之前写的一个bean标签
        //这个方法的名字,就相当于bean标签中的ID属性
        //这个方法的返回值,就相当于bean标签中的class属性
        @Bean
        public User getUser(){
            //这个属于是使用构造器注入
            return new User(1,"liu","123");//就是返回要注入到bean的对象
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            //如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载!
            ApplicationContext c = new AnnotationConfigApplicationContext(Config.class);
            User user = (User) c.getBean("getUser");
            System.out.println(user);
        }
    }
    
  3. 隐式自动装配Bean:

    byName:根据名称进行装配,所有Bean的id必须唯一,并且Bean id和需要自动注入的属性set方法值一致。

    
        
        
        
    
    
    
        
    
    

    byType:根据类型进行装配,所有Bean的类型必须唯一,并且Bean和需要自动注入的属性类型一致。

    
        
        
        
    
    
    
        
    
    
如何使用注解实现自动装配?@Autowired与@Resource的区别?

启动注解的支持/通过注解指定Spring在创建容器时要扫描的包:

  1. @Autowired:自动按照类型注入,其次是名称。如果容器中只有一个对应类型的Bean则注入,如果有多个则按照名称注入。

    required属性:标记字段是否可以为空,false可以为空,true不可以为空,默认为true。

    public class User {
    
        @Autowired(required = false)
        private Order order;
    }
    
  2. @Nullable:字段标记了这个注解,说明这个字段可以为null。

    public class User {
    
       public User(@Nullable String username) {
         this.username = username;
       }
    }
    
  3. @Resource:默认按照Bean的名称注入,其次是类型。如果容器中有对应名称的Bean则注入,如果没有则按照类型注入。

    public class User {
    
        @Resource
        private Order order;
    }
    
如何使用注解开发?Spring常用注解有哪些?

启动注解支持:

声明Bean的注解:(属性value用于指定Bean的id 默认为当前类名首字母小写)

  1. @Component:用于把当前组件对象存入Spring容器。(一般来说当一个组件不属于任何归类的情况使用)。
  2. @Controller:用于把控制层组件对象存入Spring容器。
  3. @Service:用于把业务层组件对象存入Spring容器。
  4. @Repository:用于把持久层组件对象存入Spring容器。

注:以上使用这四个注解的Bean默认别名首字母小写,如果Bean名有两个以上大写字母默认别名失效。也可以指定别名。

注入Bean的注解:

  1. @Autowired:自动按照类型注入,其次是名称。如果容器中只有一个对应类型的Bean则注入,如果有多个则按照名称注入。
  2. @Qualifier:配合@Autowired使用显示指定名称,在按照类型注入的基础上再按照名称注入(value=Bean名称)。
  3. @Resource:默认按照Bean的名称注入,其次是类型。如果容器中有对应名称的Bean则注入,如果没有则按照类型注入。
  4. @Inject:与@Autowired用法基本一致,都是默认按照类型注入,其次名称,可以与@Named配合使用指定名称注入。
  5. @Value:用于给属性赋值可以注入基本数据类型和String类型的数据。(value=${表达式})还可以使用Spring中的EL表达式。

AOP相关注解:

  1. @Aspect:声明一个切面。
  2. @After:在方法执行之后执行。
  3. @Before:在方法执行之前执行。
  4. @Around:在方法执行之前与之后执行。
  5. @PointCut:声明切点。

用于改变作用范围的注解:

  1. @Scope:用于指定Bean的作用范围。(value=singleton(单例) prototype(多例))。

生命周期相关的注解:

  1. @PreDestroy:用于指定销毁方法。
  2. @PostConstruct:用于指定初始化方法。

Java配置类注解:

  1. @Configuration:用于指定当前类是一个配置类。
  2. @ComponentScan:用于通过注解指定Spring在创建容器时要扫描的包。
  3. @Bean:用于把当前方法返回值作为Bean对象存入Spring容器中。(name=Bean名称)默认为当前方法名。
  4. @Import:用于导入其它配置类。(value=用于指定其它配置类的字节码)。
  5. @PropertySource:用于指定properties文件的位置。(value=指定文件的名称和路径)。
  6. @WiselyConfiguration:为@Configuration与@ComponentScan的组合注解,可以替代这两个注解。

环境切换:

  1. @Profile:通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。(类或方法上)。
  2. @Conditional:Spring4中可以使用此注解定义条件话的bean,通过实现Condition接口,并重写matches方法,
    从而决定该bean是否被实例化。(方法上)。

异步相关:

  1. @EnableAsync:配置类中,通过此注解开启对异步任务的支持,叙事性AsyncConfigurer接口(类上)。
  2. @Async:在实际执行的bean方法使用该注解来申明其是一个异步任务(方法上或类上所有的方法都将异步,
    需要@EnableAsync开启异步任务)。

定时任务相关:

  1. @EnableScheduling:在配置类上使用,开启计划任务的支持(类上)。
  2. @Scheduled:来申明这是一个任务,包括cron,fixDelay,fixRate等类型(方法上,需先开启计划任务的支持)。

@Enable*注解说明:(这些注解主要用来开启对xxx的支持)

  1. @EnableAspectJAutoProxy:开启对AspectJ自动代理的支持。
  2. @EnableAsync:开启异步方法的支持。
  3. @EnableScheduling:开启计划任务的支持。
  4. @EnableWebMvc:开启Web MVC的配置支持。
  5. @EnableConfigurationProperties:开启对@ConfigurationProperties注解配置Bean的支持。
  6. @EnableJpaRepositories:开启对SpringData JPA Repository的支持。
  7. @EnableTransactionManagement:开启注解式事务的支持。
  8. @EnableTransactionManagement:开启注解式事务的支持。
  9. @EnableCaching:开启注解式的缓存支持。

测试相关注解:

  1. @RunWith:运行器,Spring中通常用于对JUnit的支持。
  2. @ContextConfiguration:用来加载配置ApplicationContext,其中classes属性用来加载配置类。
如何使用Java方式配置Spring?

@Configuration + @Bean:

//这个类也会被Spring容器托管,注册到容器中,因为它自身就是一个@Component,
//@Configuration代表这是一个配置类,就和我们之前看的beans.xml一样
@Configuration
public class Config {

    //注册一个bean,就相当于我们之前写的一个bean标签
    //这个方法的名字,就相当于bean标签中的ID属性
    //这个方法的返回值,就相当于bean标签中的class属性
    @Bean
    public User getUser(){
        //这个属于是使用构造器注入
        return new User(1,"liu","123");//就是返回要注入到bean的对象
    }
}

public class Test {

    public static void main(String[] args) {
        //如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载!
        ApplicationContext c = new AnnotationConfigApplicationContext(Config.class);
        //getUser方法名等价Bean id
        User user = (User) c.getBean("getUser");
        //1 liu 123
        System.out.println(user);
    }
}

@Configuration + @ComponentScan + @Component:

@Component//默认User别名为user
public class User {

    private Integer userId;
    @Value("liu")
    private String username;
    private String password;
}

@Configuration
@ComponentScan("com.bean")//指定要扫描包下使用@Component...等注解的类
public class Config {

    //@Bean
    //public User getUser(){
    //    return new User(1,"liu","123");
    //}
}

public class Test {

    public static void main(String[] args) {
        ApplicationContext c = new AnnotationConfigApplicationContext(Config.class);
        //通过默认别名user 获取Bean
        User user = (User) c.getBean("user");
        //null liu null
        System.out.println(user);
    }
}
Spring中的代理模式是什么?有哪些?

代理模式就是给某一个对象提供一个代理对象,由代理对象控制对原对象的引用。

作用:在不修改原有代码的基础上,实现对目标对象的功能增强,扩展目标对象的功能方法。

  1. 静态代理:在运行前,通过编写代码的方式生成代理类。

    • 代理者和被代理者实现相同的接口。
    • 代理者包含被代理者对象。
    • 创建代理对象时传入被代理对象。
    • 代理者执行方法时,会调用被代理者的方法,同时扩展新的功能。

    优点:使被代理者目标更加明确,不需要关注其它业务。实现了业务分工,方便扩展。

    缺点:一个代理类只能代理一种业务,如果有多种业务,就必须创建大量的代理类。

    public interface PublicService {
    
        //模拟打官司业务场景
        String lawsuit();
    
        //吃中午饭
        String eat();
    }
    
    
    public class PublicServiceImpl implements PublicService{
    
    
        @Override
        public String lawsuit() {
            return "打官司输了";
        }
    
        @Override
        public String eat() {
            return "自己吃饭";
        }
    }
    
    
    public class AgentServiceImpl implements PublicService{
    
        //被代理对象
        private PublicService publicService;
    
        public AgentServiceImpl(PublicService publicService) {
            this.publicService = publicService;
        }
    
        @Override
        public String lawsuit() {
            return "代理打官司赢了";
        }
    
        @Override
        public String eat() {
            return publicService.eat();
        }
    }
    
    public class ServiceTest {
    
        public static void main(String[] args) {
            //原告
            PublicService publicService1 = new PublicServiceImpl();
            //被告
            PublicService publicService2 = new PublicServiceImpl();
    
            //原告自己打官司
            System.out.println("原告:" + publicService1.eat());
            System.out.println("原告:" + publicService1.lawsuit());
    
            //被告请了代理打官司
            PublicService publicService3 = new AgentServiceImpl(publicService2);
            System.out.println("被告:" + publicService3.eat());
            System.out.println("被告:" + publicService3.lawsuit());
        }
    }
    
    原告:自己吃饭
    原告:打官司输了
    被告:自己吃饭
    被告:代理打官司赢了
    
  2. 动态代理:在运行后,通过反射机制生成代理类。

    动态代理和静态代理的目的相同,都是处理被代理者。只不过动态代理的代理类是动态生成的。

    动态代理分为两大类:基于接口的动态代理,基于类的动态代理。

    基于接口:JDK动态代理,基于类:CGLib,Java字节码实现:Javasist。

    这里主要说JDK动态代理:

    Proxy:代理(用来动态生成代理对象),InvocationHandler:调用处理程序(用来处理业务)。

    优点:

    静态代理的优点,动态代理都有。
    一个动态代理类代理的接口,对应一类业务。
    只要实现了同一个接口,一个动态代理类可以代理多个类。

    public class JDKFactoryProxy implements InvocationHandler {
    
        //被代理对象
        private Object object;
    
        //通过Set方法注入被代理对象
        public void setObject(Object object) {
            this.object = object;
        }
    
        
        public Object getProxy() {
            //生成代理对象,参数1:类加载器,参数2:代理对象的实现接口,参数3:InvocationHandler的实现对象
            return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                    object.getClass().getInterfaces(),this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object invoke = method.invoke(object,args);
            System.out.println("找代理打官司又赢了");
            return invoke;
        }
    }
    
    
    public class ServiceTest {
    
        public static void main(String[] args) {
            //被代理者
            PublicService publicService = new PublicServiceImpl();
            //不存在的代理者,生成
            JDKFactoryProxy jdkFactoryProxy = new JDKFactoryProxy();
            //传入被代理者
            jdkFactoryProxy.setObject(publicService);
            //调用生成代理者方法
            PublicService service = (PublicService) jdkFactoryProxy.getProxy();
            System.out.println(service.lawsuit());
            System.out.println(service.eat());
        }
    }
    
Spring框架核心技术,AOP思想是什么?

AOP面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护。AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP在解决什么问题:在不改变原有代码的情况,增强横向逻辑代码,根本上降低耦合度,避免横切逻辑代码重复。

什么是面向切面编程?

  1. 切:指横切逻辑,原有业务逻辑代码不动,只操作横切逻辑代码。

  2. 面:横切逻辑代码往往要影响的是多个方法,每一个方法都如同一个点,多个点构成面,有一个面的概念在里面。

AOP在Spring中的作用是什么?

AOP提供声明式事务,允许用户自定义切面。

  1. 横切关注点:跨越应用程序多个模块的方法或功能。如日志,安全,缓存,事务…等。
  2. 切面(ASPECT):横切关注点被模块化的特殊对象(它是一个类)。
  3. 通知(Advice):切面必须要完成的工作(它是类中的一个方法)。
  4. 目标(Target):被通知对象。
  5. 代理(Poy):向目标对象应用通知后创建的对象。
  6. 切入点(PointCut):切面通知执行的”地点“定义。
  7. 连接点(JointPoint):与切入点匹配的执行点。

SpringAOP中通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

  1. 前置通知:方法执行前。接口MethdBeforeAdvice。
  2. 后置通知:方法执行后。接口AfterReturningAdvice.
  3. 环绕通知:方法执行前后。接口MethodInterceptor。
  4. 异常抛出通知:方法抛出异常。接口ThrowsAdvice。
  5. 引介通知:类中增加新的方法属性。接口IntroductionInterceptor。
Spring如何实现AOP?

导入aspectjweaver依赖(注:要有spring-webmvc的依赖):


    org.aspectj
    aspectjweaver
    1.9.9.1

XML方式实现方式一:使用原生Spring API接口。

引入AOP XML约束:

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd




    
    
    
    

    
    
    
        
        

        
        
        
    

public interface UserService {

    void insert();
    void delete();
    void update();
    void select();
}


public class UserServiceImpl implements UserService{

    @Override
    public void insert() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("更新了一个用户");
    }

    @Override
    public void select() {
        System.out.println("查询了一个用户");
    }
}


public class Log implements MethodBeforeAdvice {

    
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了");
    }
}


public class AfterLog implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
            throws Throwable {
        //returnValue:方法返回值
        System.out.println("执行了" + method.getName() + "方法,返回结果为:" + returnValue);
    }
}


public class Test {

    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("application-context.xml");
        //动态代理代理的是接口
        UserService userService = context.getBean("userService", UserService.class);
        userService.select();
    }
}
com.coding.UserServiceImpl的select被执行了
查询了一个用户
执行了select方法,返回结果为:null

XML方式实现方式二:自定义类,主要是切面定义。

public class DiyPointCut {

    public void before(){
        System.out.println("=============方法执行前===========");
    }

    public void after(){
        System.out.println("=============方法执行后===========");
    }
}



    


   
   
        
        
        
        
        
    
    
=============方法执行前===========
查询了一个用户
=============方法执行后===========

注解实现方式三:

@Aspect//声明这个类是一个切面
public class Pointcut {

    //在方法执行之前执行
    //expression表达式:execution(要执行的位置)
    //execution(* 包名.*.*(..))
    //第一个*表示方法返回值 *表示所有类型 然后是包名
    //第二个*表示类名,*表示所有类
    //第三个*表示方法名,*表示所有方法
    //()里边表示方法的参数, ..两个点表示任何参数
    @Before("execution(* com.coding.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("========方法执行前=========");
    }

    //在方法执行之后执行
    @After("execution(* com.coding.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("========方法执行后=========");
    }
}





        
========方法执行前=========
查询了一个用户
========方法执行后=========
Spring的声明式事务管理是什么?

Spring的声明式事务管理是通过AOP技术实现的事务管理,本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行目标方法之后根据执行情况提交或者回滚事务。

基于@Transactional注解方式:默认RuntimeException运行时异常发生回滚。

  • 一般用于接口实现类或接口实现方法上,只有在public的方法上才起作用。
  • 常用属性:
    rollbackFor={异常.class,异常.class}:指定哪些异常回滚。
    noRollbackFor={异常.class,异常.class}:指定哪些异常不回滚。
    timeout=整数 超时的秒数,一旦事务执行的时间超过timeout,超时异常,服务降级。

事务的传播行为属性:事务的传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。

  1. propagation-required: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就新建一个事务。
  2. propagation-supports: 支持当前事务,如果有就加入当前事务中;如果当前方法没有事务,就以非事务的方式执行。
  3. propagation-mandatory: 支持当前事务,如果有就加入当前事务中;如果当前没有事务,就抛出异常。
  4. propagation-requires_new: 新建事务,如果当前存在事务,就把当前事务挂起;如果当前方法没有事务,就新建事务。
  5. propagation-not-supported: 以非事务方式执行,如果当前方法存在事务就挂起当前事务;如果当前方法不存在事务,就以非事务方式执行。
  6. propagation-never: 以非事务方式执行,如果当前方法存在事务就抛出异常;如果当前方法不存在事务,就以非事务方式执行。
  7. propagation-nested: 如果当前方法有事务,则在嵌套事务内执行;如果当前方法没有事务,则与required操作类似。

在同一类中通过this调用:

  1. 一个事务方法调用另一个事务方法。

  2. 一个事务方法调用另一个非事务方法。

  3. 一个非事务方法调用另一个事务方法。

    • 事务不生效。

    • 在一个Service内部,事务方法之间嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务。

    • 可以通过提取新的Service类解决,或者把注解加到类上。

在不同类中互相调用:

  1. A类事务方法调用B类事务方法。
    propagation属性值为:REQUIRES_NEW时,代表无论调用方(方法A)是否开启了事务,被调用方(方法B)都会开启新的事务。此时如果方法B的事务出错发生了回滚,那么只会回滚方法B的事务,方法A的事务不受影响。
  2. A类事务方法调用B类非事务方法。
    在A类事务方法内,调用了B类的非事务方法。没有事务的方法一样会拥有事务特性,和A类的事务方法使用的是同一个事务,无论那个方法出错都会回滚。
  3. A类非事务方法调用B类事务方法。
    B类的事务方法正常。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/991855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号