您好,登錄后才能下訂單哦!
Spring中怎么創建Bean,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
方式1:使用Spring XML方式配置,該方式用于在純Spring 應用中,適用于簡單的小應用,當應用變得復雜,將會導致XMl配置文件膨脹 ,不利于對象管理。
<bean id="xxxx" class="xxxx.xxxx"/>
方式2:
使用@Component,@Service,@Controler,@Repository注解
這幾個注解都是同樣的功能,被注解的類將會被Spring 容器創建單例對象。
@Component : 側重于通用的Bean類 @Service:標識該類用于業務邏輯 @Controler:標識該類為Spring MVC的控制器類 @Repository: 標識該類是一個實體類,只有屬性和Setter,Getter
@Componentpublic class User{}
當用于Spring Boot應用時,被注解的類必須在啟動類的根路徑或者子路徑下,否則不會生效。
如果不在,可以使用@ComponentScan標注掃描的路徑。
spring xml 也有相關的標簽<component-scan />
@ComponentScan(value={"com.microblog.blog","com.microblog.common"})public class MicroblogBlogApplication {public static void main(String args[]){SpringApplication.run(MicroblogBlogApplication.class,args);}}
方式3:
使用@Bean注解,這種方式用在Spring Boot 應用中。
@Configuration 標識這是一個Spring Boot 配置類,其將會掃描該類中是否存在@Bean 注解的方法,比如如下代碼,將會創建User對象并放入容器中。
@ConditionalOnBean 用于判斷存在某個Bean時才會創建User Bean.
這里創建的Bean名稱默認為方法的名稱user。也可以@Bean("xxxx")定義。
@Configurationpublic class UserConfiguration{@Bean@ConditionalOnBean(Location.class)public User user(){return new User();}}
Spring boot 還為我們提供了更多類似的注解。
也和方式2一樣,也會存在掃描路徑的問題,除了以上的解決方式,還有使用Spring boot starter 的解決方式
在resources下創建如下文件。META-INF/spring.factories.
Spring Boot 在啟動的時候將會掃描該文件,從何獲取到配置類UserConfiguration。
spring.factories.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.log.config.UserConfiguration
如果不成功,請引入該依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
這個方式也是創建SpringBoot-starter的方式。
方式4:
使用注解@Import,也會創建對象并注入容器中
@Import(User.class)public class MicroblogUserWebApplication {public static void main(String args[]) {SpringApplication.run(MicroblogUserWebApplication.class, args);}}
方式5:
使用ImportSelector或者ImportBeanDefinitionRegistrar接口,配合@Import實現。
在使用一些Spring Boot第三方組件時,經常會看到@EnableXXX來使能相關的服務,這里以一個例子來實現。
創建測試類
@Slf4jpublic class House {public void run(){log.info("House run ....");}}@Slf4jpublic class User {public void run(){log.info("User run ....");}}@Slf4jpublic class Student {public void run(){log.info("Student run ....");}}
實現ImportSelector接口
selectImports方法的返回值為需要創建Bean的類名稱。這里創建User類。
@Slf4jpublic class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {log.info("MyImportSelector selectImports ...");return new String[]{User.class.getName()};}}
實現ImportBeanDefinitionRegistrar接口
beanDefinitionRegistry.registerBeanDefinition用于設置需要創建Bean的類名稱。這里創建House類。
@Slf4jpublic class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {log.info("MyImportBeanDefinitionRegistrar registerBeanDefinitions .....");BeanDefinition beanDefinition = new RootBeanDefinition(House.class.getName());beanDefinitionRegistry.registerBeanDefinition(House.class.getName(),beanDefinition);}}
創建一個配置類
這里創建Student類。
@Configurationpublic class ImportAutoconfiguration {@Beanpublic Student student(){return new Student();}}
創建EnableImportSelector注解
EnableImportSelector注解上使用@Import,引入以上的三個類。
@Retention(RetentionPolicy.RUNTIME)@Documented@Target(ElementType.TYPE)@Import({MyImportSelector.class,ImportAutoconfiguration.class,MyImportBeanDefinitionRegistrar.class})public @interface EnableImportSelector {String value();}
測試
@EnableImportSelector(value = "xxx")@SpringBootApplicationpublic class ImportDemoApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(ImportDemoApplication.class, args);User user = context.getBean(User.class);user.run();Student student = context.getBean(Student.class);student.run();House house = context.getBean(House.class);house.run();}}
輸出,可以看到,三個類User Student House都創建成功,都可從Spring 容器中獲取到。
2019-06-20 17:53:39.528 INFO 27255 --- [ main] com.springboot.importselector.pojo.User : User run ....2019-06-20 17:53:39.530 INFO 27255 --- [ main] c.s.importselector.pojo.Student : Student run ....2019-06-20 17:53:39.531 INFO 27255 --- [ main] c.springboot.importselector.pojo.House : House run ....
方式6
手動注入Bean容器,有些場景下需要代碼動態注入,以上方式都不適用。這時就需要創建 對象手動注入。
通過DefaultListableBeanFactory注入。
registerSingleton(String beanName,Object object);
這里手動使用new創建了一個Location對象。并注入容器中。
@Componentpublic class LocationRegister implements BeanFactoryAware {@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory)beanFactory;Location location = new Location();listableBeanFactory.registerSingleton("location1",location);}}
這種方式的應用場景是為接口創建動態代理對象,并向SPRING容器注冊。
比如MyBatis中的Mapper接口,Mapper沒有實現類,啟動時創建動態代理對象,將該對象注冊到容器中,使用時只要@Autowired注入即可使用,調用接口方法將會被代理攔截,進而調用相關的SqlSession執行相關的SQL業務邏輯。
可以看以下它的繼承體系
DefaultListableBeanFactory 是ConfigurableListableBeanFactory的實現類。是對BeanFactory功能的擴展。
測試代碼和以上一樣
Location location = context.getBean(Location.class);location.run();
關于Spring中怎么創建Bean問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。