<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
import lombok.Data; import org.springframework.stereotype.Component; @Component("miao") @Data public class Cat { }
被注入的JavaBean
import org.springframework.context.annotation.Configuration; @Configuration public class Config5 { }
被載入的設定類
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.beans.Cat; import yi.config.Config5; public class App2 { public static void main(String[] args) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); context.registerBean(Cat.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
在載入設定類的時候,普通的ApplicationContext不具備該功能。
可以看到其還具有掃描JavaBean註解的功能,直接把名字裝配了,沒有自定義名字的話就是類名首字母小寫。
那麼同一個實體類被載入多次會怎麼樣呢?
import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Component("miao") @Data @NoArgsConstructor public class Cat { String shout; public Cat(String shout) { this.shout = shout; } }
import org.springframework.context.annotation.Configuration; @Configuration public class Config5 { }
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.beans.Cat; import yi.config.Config5; public class App2 { public static void main(String[] args) { AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); context.registerBean(Cat.class,"1"); context.registerBean(Cat.class,"2"); context.registerBean(Cat.class,"3"); Cat miao = context.getBean("miao",Cat.class); System.out.println(miao.getShout()); } }
可以看到如果被載入多次的話,後面會覆蓋前面的。
這個和我們在設定yml檔案屬性時有異曲同工之妙,設定了就是你的設定,沒有設定就是預設的,你的設定會覆蓋預設的設定,其中那些設定背後就是一個一個的bean物件罷了。
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Component("miao") @Data @NoArgsConstructor @AllArgsConstructor public class Cat { String shout; }
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[]{"yi.beans.Cat"}; } }
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import yi.beans.MyImportSelector; @Configuration @Import(MyImportSelector.class) public class Config5 { }
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.config.Config5; public class App2 { public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
可以看到註冊了bean,並且還識別到了註解的value值。
不過這種方式還僅不於此,還可以做很多判定。
import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { boolean b = annotationMetadata.hasAnnotation("org.springframework.context.annotation.Configuration"); if (b){ //判斷是否包含這個註解 return new String[]{"yi.beans.Cat"}; }else { return new String[]{"yi.beans.Dog"}; } } }
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import yi.beans.MyImportSelector; //@Configuration @Import(MyImportSelector.class) public class Config5 { }
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.beans.Cat; import yi.config.Config5; public class App2 { public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
可以看到,我們通過API可以達到多種多樣的效果,不僅有檢視註解是否存在啊,還能獲取註解的所有引數等等。
@Configuration註解如果不被@ComponentScan掃描的話,直接被容器載入。是可以省略的,所以後面我是用@Import也是可以的。
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Component("miao") @Data @NoArgsConstructor @AllArgsConstructor public class Cat { String shout; }
實體類我通過註解給它的bean賦了名字。
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition= BeanDefinitionBuilder.rootBeanDefinition(Cat.class).getBeanDefinition(); registry.registerBeanDefinition("mao",beanDefinition); } }
AnnotationMetadata這個屬性我忽略了,因為這就是上一個定義bean的方式,可以通過後設資料對其條件判斷,你可以結合到一塊。下面是定義了bean的名字,不過還有許多ApI你可以慢慢看有空的時候。
import org.springframework.context.annotation.Import; import yi.beans.MyImportBeanDefinitionRegistrar; @Import(MyImportBeanDefinitionRegistrar.class) public class Config5 { }
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.config.Config5; public class App2 { public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } } }
可以看到這裡註解的value值被覆蓋了,在之前的方法中,一直都獲取的是註解的value值為bean的名字,由此說明,這種方式的許可權也開放了不少。
那麼如果我使用這種方式載入同一個bean載入了多次,是哪個生效呢?我來用介面模擬。可以發現是最後一個被載入的在生效。可能有人會疑問,為什麼bean名字一樣,編譯時不報異常呢?
因為一個專案是分散式的情況下,一個設定bean可能會被多個人修改,需要確保這些bean能夠覆蓋達到重新整理的效果,我猜的,不一定對。
public interface BookService { void check(); }
import yi.beans.BookService; public class BookServiceImpl1 implements BookService { @Override public void check() { System.out.println("書籍是人類進步的階梯"); } }
import yi.beans.BookService; public class BookServiceImpl2 implements BookService { @Override public void check() { System.out.println("書籍是人類進步的階梯"); } }
import yi.beans.BookService; public class BookServiceImpl3 implements BookService { @Override public void check() { System.out.println("書籍是人類進步的階梯"); } }
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; import yi.beans.impl.BookServiceImpl1; public class MyImportBeanDefinitionRegistrar1 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition= BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl1.class).getBeanDefinition(); registry.registerBeanDefinition("bookService",beanDefinition); } }
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; import yi.beans.impl.BookServiceImpl2; public class MyImportBeanDefinitionRegistrar2 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition= BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition(); registry.registerBeanDefinition("bookService",beanDefinition); } }
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; import yi.beans.impl.BookServiceImpl3; public class MyImportBeanDefinitionRegistrar3 implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition= BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl3.class).getBeanDefinition(); registry.registerBeanDefinition("bookService",beanDefinition); } }
import org.springframework.context.annotation.Import; import yi.beans.*; @Import({MyImportBeanDefinitionRegistrar1.class, MyImportBeanDefinitionRegistrar2.class, MyImportBeanDefinitionRegistrar3.class}) public class Config5 { }
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.beans.BookService; import yi.config.Config5; public class App2 { public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } BookService bookService = context.getBean("bookService", BookService.class); System.out.println(bookService.getClass()); } }
基於第七種方式,我們要是就是想要載入某個bean,又不想被其他人的覆蓋該怎麼辦呢?也就是說我們這個類無論載入到哪個位置,都不會被覆蓋。請看第八種方式。
在第七種拓展的基礎上,我們再加如下:
import yi.beans.BookService; public class BookServiceImpl4 implements BookService { @Override public void check() { System.out.println("書籍是人類進步的階梯"); } }
再加一個實現類。
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import yi.beans.impl.BookServiceImpl4; public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition(); beanDefinitionRegistry.registerBeanDefinition("bookService",beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } }
通過BeanDefinition的註冊器實名bean,實現對bean的最終裁定。
import org.springframework.context.annotation.Import; import yi.beans.*; @Import({MyImportBeanDefinitionRegistrar1.class, MyImportBeanDefinitionRegistrar2.class, MyPostProcessor.class, MyImportBeanDefinitionRegistrar3.class,}) public class Config5 { }
可以看到,我將該類沒有放到最後。
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import yi.beans.BookService; import yi.config.Config5; public class App2 { public static void main(String[] args) { ApplicationContext context=new AnnotationConfigApplicationContext(Config5.class); String[] names = context.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } BookService bookService = context.getBean("bookService", BookService.class); System.out.println(bookService.getClass()); } }
該類註冊的bean沒有被覆蓋耶。許可權是不是更開放了。bean的載入就到此為止。瞭解這些,springboot的原始碼你讀起來就不會那麼費勁了。
到此這篇關於SpringBoot Bean花式註解方法範例下篇的文章就介紹到這了,更多相關SpringBoot Bean註解方法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45