使用到的註解以下,主要針對本身寫的類html
參考 spring註解開發:ComponentScan組件掃描spring
參考:spring註解開發:Configuration&Bean
實戰數組
一、新建一個maven工程,添加以下依賴maven
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency>
二、新建一個實體 Personide
package com.yefengyu.annotation.bean; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
三、新建一個配置類(重點)測試
package com.yefengyu.annotation.config; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import(Person.class) public class MainConfig { }
四、測試代碼ui
public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } Person person1= (Person)ctx.getBean(Person.class); //bean的id默認是全類名 Person person2= (Person)ctx.getBean("com.yefengyu.annotation.bean.Person"); }
ImportSelector和Import一塊兒使用:首先編寫一個類實現ImportSelector接口MyImportSelector,而後將MyImportSelector添加到Import中,那麼MyImportSelector自定義邏輯返回須要導入的組件就會被加入到容器中。this
利用上面第三節的代碼,咱們從新添加一個類,這個類什麼都沒有,如今咱們嘗試着使用ImportSelector方式將其註冊到容器中。spa
package com.yefengyu.annotation.bean; public class Car { }
一、編寫MyImportSelector實現ImportSelector接口,重寫selectImports方法,返回的數組中每一個字符串就是要導入到容器的組件的全類名。code
package com.yefengyu.annotation; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; //自定義邏輯返回須要導入的組件 public class MyImportSelector implements ImportSelector { //返回值就是要導入到容器的組件的全類名 @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.yefengyu.annotation.bean.Car"}; } }
二、修改MainConfig配置類,使用Import註解加入MyImportSelector類,注意下面紅色部分。
package com.yefengyu.annotation.config; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class}) public class MainConfig { }
三、測試,一樣使用上面的測試代碼,能夠看出打印結果爲:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
com.yefengyu.annotation.bean.Person
com.yefengyu.annotation.bean.Car
四、針對於public String[] selectImports(AnnotationMetadata annotationMetadata)方法中的參數AnnotationMetadata有不少信息能夠幫助篩選要註冊的組件。
和使用ImportSelector方式同樣,定義一個類實現ImportBeanDefinitionRegistrar接口,重寫其中的方法,手動註冊組件。
一、定一個類,做爲要註冊的組件
package com.yefengyu.annotation.bean; public class Alarm { }
二、實現ImportBeanDefinitionRegistrar接口,手動註冊組件
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Alarm; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class)); } }
beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class));
第一個參數是組件名稱。
第二個參數是要註冊的組件的類型的定義。
AnnotationMetadata 和上一節相似。BeanDefinitionRegistry 的功能不少:
三、修改MainConfig配置類,使用Import註解加入MyImportBeanDefinitionRegistrar類,注意下面紅色部分。
package com.yefengyu.annotation.config; import com.yefengyu.annotation.MyImportBeanDefinitionRegistrar; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig { }
四、測試,一樣使用上面的測試代碼,能夠看出打印結果爲:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
com.yefengyu.annotation.bean.Person
com.yefengyu.annotation.bean.Car
alarm
一、首先建立一個待加入到容器的組件
package com.yefengyu.annotation.bean; public class Event { }
二、建立一個Spring定義的FactoryBean
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Event; import org.springframework.beans.factory.FactoryBean; //建立一個Spring定義的FactoryBean public class EventFactoryBean implements FactoryBean<Event> { //返回一個Event對象,這個對象會添加到容器中 @Override public Event getObject() throws Exception { return new Event(); } @Override public Class<?> getObjectType() { return Event.class; } //是單例? //true:這個bean是單實例,在容器中保存一份 //false:多實例,每次獲取都會建立一個新的bean; @Override public boolean isSingleton() { return true; } }
三、修改配置類,注意下面bean註解下面的代碼
package com.yefengyu.annotation.config; import com.yefengyu.annotation.EventFactoryBean; import com.yefengyu.annotation.MyImportBeanDefinitionRegistrar; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig { @Bean public EventFactoryBean eventFactoryBean() { return new EventFactoryBean(); } }
四、修改測試代碼以下:
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Person; import com.yefengyu.annotation.config.MainConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //測試EventFactoryBean Object eventFactoryBean = ctx.getBean("eventFactoryBean"); System.out.println("bean 的類型爲:" + eventFactoryBean.getClass()); Object factoryBean = ctx.getBean("&eventFactoryBean"); System.out.println("bean 的類型爲:" + factoryBean.getClass()); } }
五、結果以下:
mainConfig com.yefengyu.annotation.bean.Person com.yefengyu.annotation.bean.Car eventFactoryBean alarm bean 的類型爲:class com.yefengyu.annotation.bean.Event bean 的類型爲:class com.yefengyu.annotation.EventFactoryBean
總結:
- 默認獲取到的是工廠bean調用getObject建立的對象
ctx.getBean("eventFactoryBean");
- 要獲取工廠Bean自己,咱們須要給id前面加一個&
ctx.getBean("&eventFactoryBean");