美文网首页
spring源码学习分析(一)

spring源码学习分析(一)

作者: 息息小眠虫 | 来源:发表于2020-04-19 23:26 被阅读0次

    1. @Configuration

    标注在类上,表示这是一个spring的配置类。使用@bean注解向容器中添加一个组件

    2. @bean

    标注在方法上,表示向容器中添加一个组件。组件的类型为返回值的类型;组件的id默认为方法名,也可以指定组件的名称@bean(value="bean的名称")。

    3. @CompentScan

    标注在类上,用来进行包扫描,扫描@component、@Controller、@Service、@Repository注解标注的类,添加到容器中

    1. excludeFilters:指定一下排除策略,排除某些注解
    2. includeFilters:指定包含策略,指定包含某些注解。需要把useDefaultFilters属性设置为false(true表示扫描全部的)
    3. @ComponentScan.Filter type的类型
      1. 注解形式的FilterType.ANNOTATION @Controller @Service @Repository @Compent
      2. 指定类型的 FilterType.ASSIGNABLE_TYPE
      @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {GobaioService.class})
      
      1. aspectj类型的 FilterType.ASPECTJ(不常用)
      2. 正则表达式的 FilterType.REGEX(不常用)
      3. 自定义的 FilterType.CUSTOM
      public enum FilterType { 
          //注解形式 比如@Controller @Service @Repository @Compent 
         ANNOTATION, 
          //指定的类型 
         ASSIGNABLE_TYPE, 
         //aspectJ形式的 
         ASPECTJ, 
        //正则表达式的 
        REGEX, 
        //自定义的 CUSTOM
       }
      
      1. FilterType.CUSTOM 自定义类型如何使用
      public class GobaioFilterType implements TypeFilter { 
      @Override
      public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { 
          //获取当前类的注解源信息 
          AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); 
          //获取当前类的class的源信息 
          ClassMetadata classMetadata = metadataReader.getClassMetadata(); 
          //获取当前类的资源信息 
          Resource resource = metadataReader.getResource(); 
          if(classMetadata.getClassName().contains("dao")) {
           return true; 
          }
          return false;
       }
      }
      
        @ComponentScan(basePackages = {"com.gobaio.testcompentscan"},
      includeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM,value = GobaioFilterType.class) },useDefaultFilters = false) 
        public class MainConfig { }
      

    4. @scop

    在不指定@Scope的情况下,所有的bean都是单实例的bean,而且是饿汉加载,指定@Scope为 prototype 表示为多实例的,而且还是懒汉模式加载(IOC容器启动的时候,并不会创建对象,而是 在第一次使用的时候才会创建)
    @Scope指定的作用域方法取值:
    a. singleton 单实例的(默认)
    b. prototype 多实例的
    c. request 同一次请求
    d. session 同一个会话级别

    5. @Lazy

    Bean的懒加载
    @Lazy(主要针对单实例的bean 容器启动的时候,不创建对象,在第一次使用的时候才会创建该对象)

    6. @Conditional进行条件判断

    public class GobaioCondition implements Condition {
      @Override 
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
      }
    
    @Conditional(value = GobaioCondition.class) 
     public GobaioLog gobaioLog() { return new gobiaoLog(); }
    

    7. 往IOC 容器中添加组件的方式

    1. 通过@CompentScan +@Controller @Service @Respository @compent
      适用场景: 针对我们自己写的组件可以通过该方式来进行加载到容器中。
    2. 通过@Bean的方式来导入组件(适用于导入第三方组件的类)
    3. 通过@Import来导入组件(导入组件的id为全类名路径);通过@Import 的ImportSeletor类实现组件的导入 (导入组件的id为全类名路径);通过@Import的 ImportBeanDefinitionRegister导入组件 (可以指定bean的名称);@ImportResource(value = {"classpath:beans/beans.xml"})导入一个spring的配置文件
    4. 通过实现FacotryBean接口来实现注册 组件

    7. @Value+@PropertySource

    通过@Value +@PropertySource来给组件赋值

    @PropertySource(value = {"classpath:person.properties"}) //指定外部文件的位置
    

    8. 自动装配

    8.1 @AutoWired

    1. 自动装配首先时按照类型进行装配,若在IOC容器中发现了多个相同类型的组件,那么就按照 属性名称来进行装配
      @Autowired
      private GobaioDao gobaioDao;
      比如,我容器中有两个GobaioDao类型的组件 一个叫gobaioDao 一个叫gobaioDao2 那么我们通过@AutoWired 来修饰的属性名称时gobaioDao,那么拿就加载容器的gobaiaoDao组件,若属性名称为 gobaioDao2 那么他就加载的时gobaioDao2组件
    2. 假设我们需要指定特定的组件来进行装配,我们可以通过使用@Qualifier("gobaioDao")来指定装配的组件 或者在配置类上的@Bean加上@Primary注解
    3. 假设我们容器中即没有gobaioDao 和gobaioDao2,那么在装配的时候就会抛出异常
      No qualifying bean of type 'com.gobaio.testautowired.GobaioDao' available;
      若我们想不抛异常 ,我们需要指定 required为false的时候可以了
    @Autowired(required = false) 
    @Qualifier("gobaioDao") 
    private GobaioDao gobaioDao2;
    
    1. @Resource(JSR250规范)
      功能和@AutoWired的功能差不多一样,但是不支持@Primary 和@Qualifier的支持
    2. @InJect(JSR330规范)
      需要导入jar包依赖 功能和支持@Primary功能 ,但是没有Require=false的功能
    <dependency>
       <groupId>javax.inject</groupId> 
       <artifactId>javax.inject</artifactId>
       <version>1</version> 
    </dependency>
    
    1. 使用autowired 可以标注在方法上
      标注在set方法上
    //@Autowired 
    public void setGobaioLog(GobaioLog gobaioLog) {
      this.gobaioLog = gobaioLog; 
    }
    

    标注在构造方法上

    @Autowired 
    public GobaioAspect(GobaioLog gobaioLog) { 
      this.gobaioLog = gobaioLog;
     }
    

    标注在配置类上的入参中(可以不写)

    @Bean 
    public GobaioAspect gobaioAspect(@Autowired GobaioLog gobaioLog) { 
      GobaioAspect gobaioAspect = new GobaioAspect(gobaioLog); 
      return gobaioAspect;
     }
    

    9. @Profile

    通过@Profile注解 来根据环境来激活标识不同的Bean

    1. @Profile标识在类上,那么只有当前环境匹配,整个配置类才会生效
    2. @Profile标识在Bean上 ,那么只有当前环境的Bean才会被激活
    3. 没有标志为@Profile的bean 不管在什么环境都可以被激活
      激活切换环境的方法:
    4. 通过运行时jvm参数来切换 -Dspring.profiles.active=test|dev|prod
    5. 通过代码的方式来激活
    public static void main(String[] args) {
      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
      ctx.getEnvironment().setActiveProfiles("test","dev"); 
      ctx.register(MainConfig.class); 
      ctx.refresh(); printBeanName(ctx); 
    }
    

    相关文章

      网友评论

          本文标题:spring源码学习分析(一)

          本文链接:https://www.haomeiwen.com/subject/gbvwbhtx.html