Spring7——開發基於註解形式的spring

若雨靜夜發表於2020-06-25
開發基於註解形式的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。  

  

  

相關文章