spring基本組件如上圖:spring
最初使用xml配置文件,而後轉向註解。數組
//配置類====配置文件 @Configuration public class MainConfig { //給容器中註冊一個bean, 類型爲返回值的類型, //注意以@Bean註冊bean,Id默認爲方法名,也可經過@Bean註解的值來修改 @Bean public Person person01(){ return new Person("username",20); } } public class MainTest2 { public static void main(String args[]){ //加載註解的配置文件 ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class); //從容器中獲取bean //Person person = (Person) app.getBean("person01"); //System.out.println(person); String[] namesForBean = app.getBeanNamesForType(Person.class); for(String name:namesForBean){ System.out.println(name); } } }
@Configuration @ComponentScan(value="com.enjoy.cap2", includeFilters={ @Filter(type=FilterType.ANNOTATION, classes={Controller.class}) }, useDefaultFilters=false) public class Cap2MainConfig { //給容器中註冊一個bean, 類型爲返回值的類型, @Bean public Person person01(){ return new Person("james",20); } }
@ComponentScan value:指定要掃描的包
excludeFilters = Filter[] 指定掃描的時候按照什麼規則排除那些組件
includeFilters = Filter[] 指定掃描的時候只須要包含哪些組件
useDefaultFilters = false 默認是true,掃描全部組件,要改爲false
----掃描規則以下
FilterType.ANNOTATION:按照註解
FilterType.ASSIGNABLE_TYPE:按照給定的類型;好比按BookService類型
FilterType.ASPECTJ:使用ASPECTJ表達式
FilterType.REGEX:使用正則指定
FilterType.CUSTOM:使用自定義規則,自已寫類,實現TypeFilter接口session
//FilterType.CUSTOM的例子,經常使用
先新增自定義過濾規則類: TestTypeFilter
@ComponentScan(value="com.enjoy.cap2",includeFilters={app
@Filter(type=FilterType.CUSTOM,classes={TestTypeFilter.class})
},useDefaultFilters=false)ide
public class TestTypeFilter implements TypeFilter{ private ClassMetadata classMetadata; /* * MetadataReader:讀取到當前正在掃描類的信息 * MetadataReaderFactory:能夠獲取到其餘任何類信息 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //獲取當前類註解的信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //獲取當前正在掃描的類信息 classMetadata = metadataReader.getClassMetadata(); //獲取當前類資源(類的路徑) Resource resource = metadataReader.getResource(); String className = classMetadata.getClassName(); System.out.println("----->"+className); if(className.contains("er")){//當類包含er字符, 則匹配成功,返回true return true; } return false; } }
spring中bean默認是單例singleton,@Scope(「prototype」)爲多實例。spa
//多實例 @Scope("prototype") @Bean public Person person(){ return new Person("username",20); }
@lazy當加入此註解時,則getBean調用的時候纔會把實例加載到IOC容器。操作系統
public class WinCondition implements Condition{ /* *ConditionContext: 判斷條件可使用的上下文(環境) *AnnotatedTypeMetadata: 註解的信息 * */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // TODO 是否爲WINDOW系統 //能獲取到IOC容器正在使用的beanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //獲取當前環境變量(包括咱們操做系統是WIN仍是LINUX??) Environment environment = context.getEnvironment(); String os_name = environment.getProperty("os.name"); if(os_name.contains("Windows")){ return true; } return false; } } //加入條件註解則會按自定義的邏輯註冊,true時註冊到容器 @Conditional(WinCondition.class) @Bean("lison") public Person lison(){ System.out.println("給容器中添加lison......."); return new Person("Lison",28); }
@Import(value = { Dog.class,Cat.class,JamesImportSelector.class,JamesImportBeanDefinitionRegistrar.class }) public class JamesImportSelector implements ImportSelector{ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata){ //返回全類名的bean return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Tiger"}; } } public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /* *AnnotationMetadata:當前類的註解信息 *BeanDefinitionRegistry:BeanDefinition註冊類 * 把全部須要添加到容器中的bean加入; * @Scope */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean bean1 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog"); boolean bean2 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat"); //若是Dog和Cat同時存在於咱們IOC容器中,那麼建立Pig類, 加入到容器 //對於咱們要註冊的bean, 給bean進行封裝, if(bean1 && bean2){ RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class); registry.registerBeanDefinition("pig", beanDefinition); } } }
給容器中註冊組件的方式:prototype
1,@Bean: [導入第三方的類或包的組件],好比Person爲第三方的類, 須要在咱們的IOC容器中使用code
2,包掃描+組件的標註註解(@ComponentScan: @Controller, @Service @Reponsitory @
Componet),通常是針對 咱們本身寫的類,使用這個xml
3,@Import:[快速給容器導入一個組件] 注意:@Bean有點簡單
a,@Import(要導入到容器中的組件):容器會自動註冊這個組件,bean 的 id爲全類名
b,ImportSelector:是一個接口,返回須要導入到容器的組件的全類名數組
c,ImportBeanDefinitionRegistrar:能夠手動添加組件到IOC容器, 全部Bean的註冊可使用BeanDifinitionRegistry,寫JamesImportBeanDefinitionRegistrar實現ImportBeanDefinitionRegistrar接口便可