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

Spring 注解

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

Spring 注解

spring注解集合

事务注解
  • @EnableTransactionManagement,会额外加载 4 个 bean

    • BeanFactoryTransactionAttributeSourceAdvisor 事务切面类

    • TransactionAttributeSource 用来解析事务属性

    • TransactionInterceptor 事务拦截器

    • TransactionalEventListenerFactory 事务监听器工厂

  • @Transactional

核心
  • @Order

切面
  • @EnableAspectJAutoProxy

    • 会加载 AnnotationAwareAspectJAutoProxyCreator,它是一个 bean 后处理器,用来创建代理

    • 如果没有配置 @EnableAspectJAutoProxy,又需要用到代理(如事务)则会使用 InfrastructureAdvisorAutoProxyCreator 这个 bean 后处理器

组件扫描与配置类
  • @Component

  • @Controller

  • @Service

  • @Repository

  • @ComponentScan

  • @Conditional

  • @Configuration

    • 配置类其实相当于一个工厂, 标注 @Bean 注解的方法相当于工厂方法

    • @Bean 不支持方法重载, 如果有多个重载方法, 仅有一个能入选为工厂方法

    • @Configuration 默认会为标注的类生成代理, 其目的是保证 @Bean 方法相互调用时, 仍然能保证其单例特性

    • @Configuration 中如果含有 BeanFactory 后处理器, 则实例工厂方法会导致 MyConfig 提前创建, 造成其依赖注入失败,解决方法是改用静态工厂方法或直接为 @Bean 的方法参数依赖注入, 针对 Mapper 扫描可以改用注解方式

    • 代码测试

      package day04.boot;
      
      import org.mybatis.spring.annotation.MapperScan;
      import org.mybatis.spring.mapper.MapperScannerConfigurer;
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.context.annotation.AnnotationConfigUtils;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.support.GenericApplicationContext;
      
      public class TestConfiguration {
          public static void main(String[] args) {
              GenericApplicationContext context = new GenericApplicationContext();
              AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
              context.registerBean("myConfig", MyConfig.class);
              context.refresh();
      //        System.out.println(context.getBean(MyConfig.class).getClass());
          }
      
          @Configuration
          @MapperScan("aaa")
          // 注意点1: 配置类其实相当于一个工厂, 标注 @Bean 注解的方法相当于工厂方法
          static class MyConfig {
              // 注意点2: @Bean 不支持方法重载, 如果有多个重载方法, 仅有一个能入选为工厂方法
              // 注意点3: @Configuration 默认会为标注的类生成代理, 其目的是保证 @Bean 方法相互调用时, 仍然能保证其单例特性
              
      
              
      
              
      
              // 注意点4: @Configuration 中如果含有 BeanFactory 后处理器, 则实例工厂方法会导致 MyConfig 提前创建, 造成其依赖注入失败
              // 解决方法是该用静态工厂方法或直接为 @Bean 的方法参数依赖注入, 针对 MapperScanner 可以改用注解方式
              @Value("${java.class.version}")
              private String version;
      
              
      
              @Bean
              public Bean3 bean3() {
                  System.out.println("bean3() " + version);
                  return new Bean3();
              }
          }
      
          static class Bean1 {
      
          }
      
          static class Bean2 {
      
          }
      
          static class Bean3 {
      
          }
      }
      
  • @Bean

  • @Import

    • 四种用法

      ① 引入单个 bean

      ② 引入一个配置类

      ③ 通过 Selector 引入多个类

      ④ 通过 beanDefinition 注册器

      代码测试
      package day04.boot;
      
      import org.springframework.beans.factory.support.BeanDefinitionBuilder;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.context.annotation.*;
      import org.springframework.context.support.GenericApplicationContext;
      import org.springframework.core.type.AnnotationMetadata;
      
      public class TestImport {
          public static void main(String[] args) {
              GenericApplicationContext context = new GenericApplicationContext();
              AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
              context.registerBean(MyConfig.class);
              context.refresh();
      
              for (String name : context.getBeanDefinitionNames()) {
                  System.out.println(name);
              }
      
          }
      
          @Configuration
      //    @Import(Bean1.class) // 1. 引入单个 bean
      //    @Import(OtherConfig.class) // 2. 引入一个配置类
          @Import(MySelector.class) // 3. 通过 Selector 引入多个类
      //    @Import(MyRegistrar.class) // 4. 通过 beanDefinition 注册器
          static class MyConfig {
      
          }
      
          static class MySelector implements DeferredImportSelector {
              @Override
              public String[] selectImports(AnnotationMetadata importingClassMetadata) {
                  return new String[]{Bean3.class.getName(), Bean4.class.getName()};
              }
          }
      
          static class MyRegistrar implements ImportBeanDefinitionRegistrar {
              @Override
              public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                  registry.registerBeanDefinition("bean5", BeanDefinitionBuilder.genericBeanDefinition(Bean5.class).getBeanDefinition());
              }
          }
      
          static class Bean5 {
      
          }
      
          static class Bean3 {
      
          }
      
          static class Bean4 {
      
          }
      
          static class Bean1 {
      
          }
      
          @Configuration
          static class OtherConfig {
              @Bean
              public Bean2 bean2() {
                  return new Bean2();
              }
          }
      
          static class Bean2 {
      
          }
      
      
      }
      
    • 解析规则

      • 同一配置类中, @Import 先解析 @Bean 后解析

      • 同名定义, 默认后面解析的会覆盖前面解析的

      • 不允许覆盖的情况下, 如何能够让 MyConfig(主配置类) 的配置优先? (虽然覆盖方式能解决)

      • 采用 DeferredImportSelector,因为它最后工作, 可以简单认为先解析 @Bean, 再 Import

      • 代码测试

        package day04.boot;
        
        import org.springframework.beans.factory.support.DefaultListableBeanFactory;
        import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
        import org.springframework.context.annotation.*;
        import org.springframework.context.support.GenericApplicationContext;
        import org.springframework.core.type.AnnotationMetadata;
        
        public class TestDeferredImport {
        
            public static void main(String[] args) {
                GenericApplicationContext context = new GenericApplicationContext();
                DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
                beanFactory.setAllowBeanDefinitionOverriding(false); // 不允许同名定义覆盖
                AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
                context.registerBean(MyConfig.class);
                context.refresh();
        
                System.out.println(context.getBean(MyBean.class));
            }
        
            // 1. 同一配置类中, @Import 先解析  @Bean 后解析
            // 2. 同名定义, 默认后面解析的会覆盖前面解析的
            // 3. 不允许覆盖的情况下, 如何能够让 MyConfig(主配置类) 的配置优先? (虽然覆盖方式能解决)
            // 4. DeferredImportSelector 最后工作, 可以简单认为先解析 @Bean, 再 Import
            @Configuration
            @Import(MySelector.class)
            static class MyConfig { // 主配置 - 程序员编写的
                @Bean
                public MyBean myBean() {
                    return new Bean1();
                }
            }
        
            static class MySelector implements DeferredImportSelector {
        
                @Override
                public String[] selectImports(AnnotationMetadata importingClassMetadata) {
                    return new String[]{OtherConfig.class.getName()};
                }
            }
        
            @Configuration
            static class OtherConfig { // 从属配置 - 自动配置
                @Bean
                @ConditionalOnMissingBean
                public MyBean myBean() {
                    return new Bean2();
                }
            }
        
            interface MyBean {
        
            }
        
            static class Bean1 implements MyBean {
        
            }
        
            static class Bean2 implements MyBean {
        
            }
        
        }
        
  • @Lazy

    • 加在类上,表示此类延迟实例化、初始化

    • 加在方法参数上,此参数会以代理方式注入

  • @PropertySource

依赖注入
  • @Autowired

  • @Qualifier

  • @Value

mvc mapping
  • @RequestMapping,可以派生多个注解如 @GetMapping 等

mvc rest
  • @RequestBody

  • @ResponseBody,组合 @Controller => @RestController

  • @ResponseStatus

mvc 统一处理
  • @ControllerAdvice,组合 @ResponseBody => @RestControllerAdvice

  • @ExceptionHandler

mvc 参数
  • @PathVariable

mvc ajax
  • @CrossOrigin

boot auto
  • @SpringBootApplication

  • @EnableAutoConfiguration

  • @SpringBootConfiguration

boot condition
  • @ConditionalOnClass,classpath 下存在某个 class 时,条件才成立

  • @ConditionalOnMissingBean,beanFactory 内不存在某个 bean 时,条件才成立

  • @ConditionalOnProperty,配置文件中存在某个 property(键、值)时,条件才成立

boot properties
  • @ConfigurationProperties,会将当前 bean 的属性与配置文件中的键值进行绑定

  • @EnableConfigurationProperties,会添加两个较为重要的 bean

    • ConfigurationPropertiesBindingPostProcessor,bean 后处理器,在 bean 初始化前调用下面的 binder

    • ConfigurationPropertiesBinder,真正执行绑定操作

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937701.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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