spring注解开发:容器中注册组件方式
1、包掃描+組件標注注解
使用到的注解如下,主要針對自己寫的類
- @Controller
- @Service
- @Repository
- @Component
- @ComponentScan
參考 spring注解開發:ComponentScan組件掃描
2、使用bean注解
主要使用場景:導入第三方包里面的組件,使用到的注解:
- @Bean
3、使用@Import注解
- 使用方式:@Import(要導入到容器中的組件);容器中就會自動注冊這個組件
- bean的id默認是全類名
- 示例:@Import(value = {Person.class})
實戰
1、新建一個maven工程,添加如下依賴
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version> </dependency>2、新建一個實體 Person
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;}@Overridepublic String toString(){return "Person{" +"name='" + name + '\'' +", age=" + age +'}';} }3、新建一個配置類(重點)
package com.yefengyu.annotation.config;import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*;@Configuration public class MainConfig { }4、測試代碼
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"); }4、使用ImportSelector
ImportSelector和Import一起使用:首先編寫一個類實現ImportSelector接口MyImportSelector,然后將MyImportSelector添加到Import中,那么MyImportSelector自定義邏輯返回需要導入的組件就會被加入到容器中。
利用上面第三節的代碼,我們重新添加一個類,這個類什么都沒有,現在我們嘗試著使用ImportSelector方式將其注冊到容器中。
package com.yefengyu.annotation.bean;public class Car { }1、編寫MyImportSelector實現ImportSelector接口,重寫selectImports方法,返回的數組中每個字符串就是要導入到容器的組件的全類名。
package com.yefengyu.annotation;import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata;//自定義邏輯返回需要導入的組件 public class MyImportSelector implements ImportSelector {//返回值就是要導入到容器的組件的全類名 @Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata){return new String[]{"com.yefengyu.annotation.bean.Car"};} }2、修改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, }) public class MainConfig { }3、測試,同樣使用上面的測試代碼,可以看出打印結果為:
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.Person4、針對于public String[] selectImports(AnnotationMetadata annotationMetadata)方法中的參數AnnotationMetadata有很多信息可以幫助篩選要注冊的組件。
5、使用ImportBeanDefinitionRegistrar
和使用ImportSelector方式一樣,定義一個類實現ImportBeanDefinitionRegistrar接口,重寫其中的方法,手動注冊組件。
1、定一個類,作為要注冊的組件
package com.yefengyu.annotation.bean;public class Alarm { }2、實現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 {@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata,BeanDefinitionRegistry beanDefinitionRegistry){beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class));} }beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class));
第一個參數是組件名稱。
第二個參數是要注冊的組件的類型的定義。
AnnotationMetadata 和上一節類似。BeanDefinitionRegistry 的功能很多:
3、修改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, .class}) public class MainConfig { }4、測試,同樣使用上面的測試代碼,可以看出打印結果為:
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.Car6、使用FactoryBean
1、首先創建一個待加入到容器的組件
package com.yefengyu.annotation.bean;public class Event { }2、創建一個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對象,這個對象會添加到容器中 @Overridepublic Event getObject()throws Exception{return new Event();}@Overridepublic Class<?> getObjectType(){return Event.class;}//是單例?//true:這個bean是單實例,在容器中保存一份//false:多實例,每次獲取都會創建一個新的bean; @Overridepublic boolean isSingleton(){return true;} }3、修改配置類,注意下面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 {@Beanpublic EventFactoryBean eventFactoryBean(){return new EventFactoryBean();} }4、修改測試代碼如下:
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);}//測試EventFactoryBeanObject eventFactoryBean = ctx.getBean("eventFactoryBean");System.out.println("bean 的類型為:" + eventFactoryBean.getClass());Object factoryBean = ctx.getBean("&eventFactoryBean");System.out.println("bean 的類型為:" + factoryBean.getClass());} }5、結果如下:
mainConfig com.yefengyu.annotation.bean.Person com.yefengyu.annotation.bean.Car eventFactoryBean alarm總結:
- 默認獲取到的是工廠bean調用getObject創建的對象
??? ctx.getBean("eventFactoryBean");
- 要獲取工廠Bean本身,我們需要給id前面加一個&
??? ctx.getBean("&eventFactoryBean");
?
轉載于:https://www.cnblogs.com/ye-feng-yu/p/11080522.html
總結
以上是生活随笔為你收集整理的spring注解开发:容器中注册组件方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker的网络模式和跨主机通信
- 下一篇: Verilog设计分频器(面试必看)