開發基於註解形式的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。