1. 程式人生 > 實用技巧 >Spring7——開發基於註解形式的spring

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。