SpringBoot Bean花式注解方法示例下篇
1.容器初始化完成后注入bean
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對象罷了。
2.導入源的編程式處理
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也是可以的。
3.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;
}實體類我通過注解給它的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加載了多次,是哪個生效呢?我來用接口模擬??梢园l(fā)現是最后一個被加載的在生效。可能有人會疑問,為什么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());
}
}
4.最終裁定
基于第七種方式,我們要是就是想要加載某個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注解方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring?Boot項目部署命令java?-jar的各種參數及作用詳解
這篇文章主要介紹了Spring?Boot項目部署命令java?-jar的各種參數及作用的相關資料,包括設置內存大小、垃圾回收器、線程棧大小、系統(tǒng)屬性等,還介紹了SpringBoot專用參數,如修改端口、指定配置文件等,需要的朋友可以參考下2025-04-04
關于@RequestBody和@RequestParam注解的使用詳解
這篇文章主要介紹了關于@RequestBody和@RequestParam注解的使用詳解,本文十分具有參考意義,希望可以幫助到你,如果有錯誤的地方還望不吝賜教2023-03-03

