zoukankan      html  css  js  c++  java
  • Spring7——开发基于注解形式的spring

    开发基于注解形式的spring
    SpringIOC容器的2种形式:
    (1)xml配置文件:applicationContext.xml;
    存bean:<bean>
    取bean:
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    

    (2)注解:带有@Configuration注解的类(配置类)

    存bean:@Bean+方法的返回值
    //配置类,相当于applicationContext.xml
    @Configuration
    public class MyConfig {
    
    
        @Bean //id=方法名(myStudent)
        public Student myStudent(){
            Student student=new Student(2,"fg",34);
            return student;
        }
    }
    

    取bean: 

    ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
    Student myStudent = (Student) context.getBean("myStudent");
    
    注意:两种形式获取的IOC是独立的
     
    注解形式向IOC容器存放bean详解:
    1.必须有@Configuration
    2.形式:
    2.1 三层组件(Controller、Service、Dao):
                (1)将三层组件分别加注解@Controller、@Service、@Repository等价于@Commponent
                 (2)纳入扫描器
    a.xml配置
    <context:component-scan base-package="org.ghl.controller"></context:component-scan>
    
    b.注解形式     
    component-scan只对三层组件负责。
     
     
    给扫描器指定规则:
                    过滤类型:FilterType(ANNOTATION, ASSIGNABLE_TYPE, CUSTOM)
                    ANNOTATION:三层注解类型@Controller、@Service、@Repository等价于@Commponent
    排除:
    @ComponentScan(value = "org.ghl",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION ,value = {Service.class,Repository.class})})
    包含:(有默认行为,可以通过useDefaultFilters禁止)
    @ComponentScan(value = "org.ghl",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION ,value = {Service.class,Repository.class})},useDefaultFilters = false)
    

      ASSIGNABLE_TYPE:指具体的类。

    @ComponentScan(value = "org.ghl",includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE ,value = {StudentController.class})},useDefaultFilters = false)
    
    区分:ANNOTATION:Service.class指标有@Service的所有类;
              ASSIGNABLE_TYPE:指具体的类。
                    CUSTOM:自定义:自己定义规则
    @ComponentScan(value = "org.ghl",includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM ,value = {MyFilter.class})},useDefaultFilters = false)
    
    public class MyFilter implements TypeFilter {
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            //拿到扫描器value = "org.ghl"包中的所有标有三层组件注解类的名字
            String className = classMetadata.getClassName();
            //只过滤出和student相关的三层组件
            if (className.contains("Student")){
                return true;  //表示包含
            }
            return false; //表示排除
        }
    }
    

      

    2.2 非三层组件(Student.clss/转换器等):
    (1)@Bean+方法的返回值,id的默认值为方法名,也可以通过@Bean("stu")修改。
    (2)import/FactoryBean
     
    bean的作用域

    (@Scope("singleton"))scope="singleton":单例
    scope="prototype":原型、多实例。
    执行的时机(产生bean的时机):
            singleton:容器在初始化时,就创建对象,且只创建一次; 也支持延迟加载:在第一次使用时,创建对象。在config中加入@Lazy。
            prototype:容器在初始化时,不创建对象,在每次使用时(每次从容器获取对象时),再创建对象。
            
    条件注解
    可以让某一个Bean在某些条件下加入IOC容器。
    (1)准备bean;
    (2)增加条件bean:给每个bean设置条件,必须实现Condition接口。
    (3)根据条件加入IOC容器
     
    回顾给IOC加入Bean的方法:
           注解:全部在@Configuration配置中设置:
                    三层组件:扫描器+三层注解
                    非三层组件:(1)@Bean+返回值
                                         (2)@import
                                         (3)FactoryBean(工厂Bean)
     
    @import使用:
            (1)直接编写到@Import中;
    @Import({Apple.class,Banana.class})
            (2)自定义ImportSelector接口的实现类,通过selectimports方法实现(方法的返回值就是要纳入IOC容器的Bean)。并告知程序自己编写的实现类。
    public class MyImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            return new String[]{"org.ghl.entity.Apple","org.ghl.entity.Banana"}; //方法的返回值就是要纳入IOC容器的Bean
        }
    }
    @Import({MyImportSelector.class})
    

        (3)编写ImporBeanDefinitionRegistrar接口的实现类并重写方法。 

    public class MyImporBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
            //BeanDefinition beanDefinition=new RootBeanDefinition(Orange.class);
            BeanDefinition beanDefinition=new RootBeanDefinition("org.ghl.entity.Orange");
            beanDefinitionRegistry.registerBeanDefinition("myorange",beanDefinition);
    
    
        }
    }  
    @Import({MyImporBeanDefinitionRegistrar.class})
    

      

    FactoryBean(工厂Bean)
            1.写实现类和重写方法;  
    public class MyFactoryBean implements FactoryBean{
        @Override
        public Object getObject() throws Exception {
            return new Apple();
        }
    
        @Override
        public Class<?> getObjectType() {
            return Apple.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    

      2.注册到@Bean中  

    @Bean
    public FactoryBean<Apple>  myFactoryBean(){
        return new MyFactoryBean();
    }
    

    注意:需要通过&区分获取的对象是哪一个。不加&,获取的是最内部真实的apple,如果加&,获取的是FactoryBean。  

      

      

  • 相关阅读:
    都说程序员钱多空少,程序员真的忙到没时间回信息了吗?
    C/C++知识分享: 函数指针与指针函数,看完这篇你还能不懂?
    C++的那些事儿:从电饭煲到火箭,C++无处不在
    年薪90万程序员不如月入3800公务员?安稳与高收入,到底如何选择?
    【C++学习笔记】C++ 标准库 std::thread 的简单使用,一文搞定还不简单?
    C语言既有高级语言又有低级语言的特点,但为什么它不是低级语言呢?
    【C++学习笔记】看完这篇,C++ 的链接问题不怕你搞不明白!
    既然C++这么难学,为什么还有人“自讨苦吃”?
    编程语言这么多,为什么就只有C 语言能一直得到 SQLite 的青睐?
    初学者疑惑:C语言中,函数反复调用会有什么问题?
  • 原文地址:https://www.cnblogs.com/ghlz/p/13191225.html
Copyright © 2011-2022 走看看