zoukankan      html  css  js  c++  java
  • Spring源码系列6

    1.@Controller/@Service/@Repository/@Component,结合包扫描

    这种方式是我们最常使用的方式,只需要在组件类上加上这四类注解即可。

    2.@Bean[导入第三方包的组件]

    这种方式在SpringBoot中最为常见。无论是我们自己定义组件,还是引入第三方的组件(比如数据源),都可以使用该方式。 容器中组件的id默认为@Bean对应方法的方法名。

    使用@Scope

    @Bean
    @Scope("prototype")//指定Bean的作用域
    public class Apple {
    }

    使用@Lazy

    @Bean
    @Lazy //指定Bean为懒加载
    public class Banana {
    }

    使用@Conditional,条件成立才注册

    public class MainConfig {
     
        @Bean("Windows")
        @Conditional(value = {WindowsCondition.class})
        public  WindowsBean getWin(){
            return  new WindowsBean();
        }
     
        @Bean("Linux")
        @Conditional(value = {LinuxCondition.class})
        public  LinuxBean getLinus(){
            return new LinuxBean();
        }
    
    public class LinuxCondition implements Condition {
    
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            Environment environment =  conditionContext.getEnvironment();
            String property = environment.getProperty("os.name");
            if(property.contains("Linux")){
                return  true;
            }
            return false;
        }
    
    public class WindowsCondition implements Condition {
     
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            Environment environment =  conditionContext.getEnvironment();
            String property = environment.getProperty("os.name");
     
            if(property.contains("Windows")){
                return true;
            }
            return false;
        }
        
    }

    使用@ComponentScan指定扫描类型,使用TypeFilter指定过滤规则

    //排除扫描类型
    @ComponentScan(value = "com.spring", excludeFilters = {
        //过滤注解类型,@Controller @Repository
        @Filter(type = FilterType.ANNOTATION, classes = { Controller.class,Repository.class })
    })
    
    //指定扫描类型
    @ComponentScan(value = "com.spring", includeFilters = {
        //过滤注解类型  @Controller @Repository
        @Filter(type = FilterType.ANNOTATION, classes = { Controller.class,Repository.class })
    },useDefaultFilters = false)//注意:使用扫描指定类型时,需要禁用默认规则
    
    //【自定义类型】
    @ComponentScans(value= {
        @ComponentScan(value = "com.spring", includeFilters = {
            @Filter(type = FilterType.ANNOTATION, classes = { Controller.class,Repository.class }) ,
            @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = (BookService.class)),
            
            @Filter(type = FilterType.CUSTOM,classes = (MyTypeFilter.class)) //自定义类型
        },useDefaultFilters = false)
    })
    
    class MyTypeFilter implements TypeFilter {
    
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                throws IOException {
            //获取当前类注解的信息
            AnnotationMetadata nnnotationmetadata = metadataReader.getAnnotationMetadata();
            //获取当前正在扫描的类的类信息
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //获取当前类的资源信息(类的路径)
            Resource resource = metadataReader.getResource();
    
            String className = classMetadata.getClassName();
            if (className.contains("er")) {
                return true;
            }
            return false;
        }
    
    }

    3.@Import[快速给容器导入一个组件]

    @Import

    @Import(要导入到容器中的组件):容器中就会自动注册这个Bean,id默认为全类名。

    @Configuration
    @Import({Color.class}) //为容器导入Color组件
    public class MainConfig{
    }

    @Import + ImportSelector

    使用ImportSelector指定要导入的组件的全类名

    @Configuration
    @Import({MyImportSelector.class}))
    public class MainConfig{
    }
    
    public class MyImportSelector implements ImportSelector {
    
        //方法返回值就是要导入到容器中的组件的全类名
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.scorpios.bean.Color","com.scorpios.bean.Blue"};
        }
    }

    @Import + ImportBeanDefinitionRegistrar

    使用ImportBeanDefinitionRegistrar手动注册Bean

    @Configuration
    @Import({MyImportBeanDefinitionRegistrar.class}))
    public class MainConfig{
    }
    
    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        /**
         * 调用BeanDefinitionRegistry.registerBeanDefinition,手工来注册Bean
         */
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            boolean definition = registry.containsBeanDefinition("com.scorpios.bean.Color");
            boolean definition2 = registry.containsBeanDefinition("com.scorpios.bean.Blue");
            if(definition && definition2){
                RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
                //手动注册Bean。指定bean名
                registry.registerBeanDefinition("rainBow", beanDefinition);
            }
        }
    }

    4.使用Spring提供的FactoryBean

    @Configuration
    public class MainConfig {
    
        @Bean
        public ColorFactoryBean coloFactoryBean() {
            return new ColorFactoryBean();
        }
    
    }
    
    //定义一个FactoryBean
    public class ColorFactoryBean implements FactoryBean<Color> {
    
        //getBean("colorFactoryBean")时,会调用该方法
        public Color getObject() throws Exception {
            return new Color();
        }
    
        
        public Class<?> getObjectType() {
            return Color.class;//指定Bean的类型
        }
    
        public boolean isSingleton() {
            return false;
        }
    
    }
    
    //虽然指定的是ColorFactoryBean,但实际上获取到的是 Color
    Object bean = context.getBean("colorFactoryBean")
    System.out.println("Bean的类型" + bean.getClass);//【结果为Color类型】
    
    //要获取FactoryBean本身,只需加个 & 符号
    Object bean = context.getBean("&colorFactoryBean")
    System.out.println("Bean的类型" + bean.getClass);//【结果为ColorFactoryBean类型】
  • 相关阅读:
    C# in Depth Third Edition 学习笔记-- Lambda表达式和表达式树
    几个比较实用的.Net 反编译工具
    使用Microsoft.Practices.EnterpriseLibrary.Data调用存数过程Output参数注意事项
    C# in Depth Third Edition 学习笔记-- C#2的一些特性
    C# in Depth Third Edition 学习笔记-- 可空类型
    C# in Depth Third Edition 学习笔记-- C#2.0: 解决C#1.0的问题 1 泛型
    C# in Depth Third Edition 学习笔记-- 值类型和引用
    .Net 程序员应该知道的工具和网站
    HTML 转 PDF
    C#、ASP.NET获取当前应用程序的绝对路径,获取程序工作路径 (转帖)
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/12764108.html
Copyright © 2011-2022 走看看