BeanDefinition
BeanDefinition表示Bean定義,BeanDefinition中存在很多屬性用來描述一個Bean的特點。比如:
- class,表示Bean類型
- scope,表示Bean作用域,單例或原型等
- lazyInit:表示Bean是否是懶加載
- initMethodName:表示Bean初始化時要執行的方法
- destroyMethodName:表示Bean銷毀時要執行的方法
- 還有很多…
BeanDefinitionReader
接下來,我們來介紹幾種在Spring源碼中所提供的BeanDefinition讀取器(BeanDefinitionReader),這些BeanDefinitionReader在我們使用Spring時用得少,但在Spring源碼中用得多,相當于Spring源碼的基礎設施。
AnnotatedBeanDefinitionReader
可以直接把某個類轉換為BeanDefinition,并且會解析該類上的注解,比如
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);// 將User.class解析為BeanDefinition
annotatedBeanDefinitionReader.register(User.class);System.out.println(context.getBean("user"));
注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description
XmlBeanDefinitionReader
可以解析標簽
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");System.out.println(context.getBean("user"));
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner是掃描器,但是它的作用和BeanDefinitionReader類似,它可以進行掃描,掃描某個包路徑,對掃描到的類進行解析,比如,掃描到的類上如果存在@Component注解,那么就會把這個類解析為一個BeanDefinition,比如:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.zhouyu");System.out.println(context.getBean("userService"));
BeanFactory
BeanFactory表示**Bean工廠**,所以很明顯,BeanFactory會負責創建Bean,并且提供獲取Bean的API。
而ApplicationContext是BeanFactory的一種,在Spring源碼中,是這么定義的:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
}
ApplicationContext
上面有分析到,ApplicationContext是個接口,實際上也是一個BeanFactory,不過比BeanFactory更加強大,比如:
- HierarchicalBeanFactory:擁有獲取父BeanFactory的功能
- ListableBeanFactory:擁有獲取beanNames的功能
- ResourcePatternResolver:資源加載器,可以一次性獲取多個資源(文件資源等等)
- EnvironmentCapable:可以獲取運行時環境(沒有設置運行時環境功能)
- ApplicationEventPublisher:擁有廣播事件的功能(沒有添加事件監聽器的功能)
- MessageSource:擁有國際化功能
AnnotationConfigApplicationContext
- ConfigurableApplicationContext:繼承了ApplicationContext接口,添加事件監聽器、添加BeanFactoryPostProcessor、設置Environment,獲取ConfigurableListableBeanFactory等功能
- AbstractApplicationContext:實現了ConfigurableApplicationContext接口
- GenericApplicationContext:繼承了AbstractApplicationContext,實現了BeanDefinitionRegistry接口,擁有了所有ApplicationContext的功能,并且可以注冊BeanDefinition,注意這個類中有一個屬性(DefaultListableBeanFactory beanFactory)
- AnnotationConfigRegistry:可以單獨注冊某個類為BeanDefinition(可以處理該類上的@Configuration注解,已經可以處理@Bean注解),同時可以掃描。
- AnnotationConfigApplicationContext:繼承了GenericApplicationContext,實現了AnnotationConfigRegistry接口,擁有了以上所有的功能
ClassPathXmlApplicationContext
它也是繼承了AbstractApplicationContext,但是相對于AnnotationConfigApplicationContext而言,功能沒有AnnotationConfigApplicationContext強大,比如不能注冊BeanDefinition。
OrderComparator
OrderComparator是Spring所提供的一種比較器,可以用來根據@Order注解或實現Ordered接口來執行值進行筆記,從而可以進行排序。
BeanPostProcessor
BeanPostProcess表示Bena的后置處理器,我們可以定義一個或多個BeanPostProcessor,比如通過一下代碼定義一個BeanPostProcessor:
@Component
public class ZhouyuBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if ("userService".equals(beanName)) {System.out.println("初始化前");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if ("userService".equals(beanName)) {System.out.println("初始化后");}return bean;}
}
**一個BeanPostProcessor可以在任意一個Bean的初始化之前以及初始化之后去額外的做一些用戶自定義的邏輯,當然,我們可以通過判斷beanName來進行針對性處理(針對某個Bean,或某部分Bean)。**可以通過定義BeanPostProcessor來干涉Spring創建Bean的過程。
BeanFactoryPostProcessor
BeanFactoryPostProcessor表示Bean工廠的后置處理器,其實和BeanPostProcessor類似,BeanPostProcessor是干涉Bean的創建過程,BeanFactoryPostProcessor是干涉BeanFactory的創建過程。比如,我們可以這樣定義一個BeanFactoryPostProcessor:
@Component
public class ZhouyuBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("加工beanFactory");}
}
我們可以在postProcessBeanFactory()方法中對BeanFactory進行加工。
FactoryBean
上面提到,我們可以通過BeanPostPorcessor來干涉Spring創建Bean的過程,但是如果我們想一個Bean完完全全由我們來創造,也是可以的,比如通過FactoryBean:
@Component
public class ZhouyuFactoryBean implements FactoryBean {@Overridepublic Object getObject() throws Exception {UserService userService = new UserService();return userService;}@Overridepublic Class<?> getObjectType() {return UserService.class;}
}
通過上面這段代碼,我們自己創造了一個UserService對象,并且它將成為Bean。但是通過這種方式創造出來的UserService的Bean,只會經過**初始化后**,其他Spring的生命周期步驟是不會經過的,比如依賴注入。
有同學可能會想到,通過@Bean也可以自己生成一個對象作為Bean,那么和FactoryBean的區別是什么呢?其實在很多場景下他倆是可以替換的,但是站在原理層面來說的,區別很明顯,@Bean定義的Bean是會經過完整的Bean生命周期的。
ExcludeFilter和IncludeFilter
這兩個Filter是Spring掃描過程中用來過濾的。ExcludeFilter表示排除過濾器,IncludeFilter表示包含過濾器。
比如以下配置,表示掃描com.zhouyu這個包下面的所有類,但是排除UserService類,也就是就算它上面有@Component注解也不會成為Bean。
@ComponentScan(value = "com.zhouyu",excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}
再比如以下配置,就算UserService類上沒有@Component注解,它也會被掃描成為一個Bean。
@ComponentScan(value = "com.zhouyu",includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}
FilterType分為:
- ANNOTATION:表示是否包含某個注解
- ASSIGNABLE_TYPE:表示是否是某個類
- ASPECTJ:表示否是符合某個Aspectj表達式
- REGEX:表示是否符合某個正則表達式
- CUSTOM:自定義
在Spring的掃描邏輯中,默認會添加一個AnnotationTypeFilter給includeFilters,表示默認情況下Spring掃描過程中會認為類上有@Component注解的就是Bean。
EnvironmentAware
凡注冊到Spring容器內的bean,實現了EnvironmentAware接口重寫setEnvironment方法后,在工程啟動時可以獲得application.properties的配置文件配置的屬性值。
public class DataSourceAutoConfig implements EnvironmentAware {@Overridepublic void setEnvironment(Environment environment) {String prefix = "router.jdbc.datasource.";dbCount = Integer.valueOf(environment.getProperty(prefix + "dbCount"));tbCount = Integer.valueOf(environment.getProperty(prefix + "tbCount"));String dataSources = environment.getProperty(prefix + "list");for (String dbInfo : dataSources.split(",")) {Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, prefix + dbInfo, Map.class);dataSourceMap.put(dbInfo, dataSourceProps);}}
AbstractRoutingDataSource
動態數據源配置需要繼承 AbstractRoutingDataSource 實現 determineCurrentLookupKey 方法。
public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return "db" + DBContextHolder.getDBKey();}
}
ApplicationContext
ApplicationContext,繼承于 ListableBeanFactory,也就繼承了關于 BeanFactory 方法,比如一些 getBean 的方法。另外 ApplicationContext 本身是 Central 接口,但目前還不需要添加一些獲取 ID 和父類上下文,所以暫時沒有接口方法的定義。
public interface ApplicationContext extends ListableBeanFactory {
}
ConfigurableApplicationContext
ApplicationListener
ApplicationContextAware
public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {SpringContextUtils.applicationContext = applicationContext;}public static Object getBean(String name) {return applicationContext.getBean(name);}public static <T> T getBean(Class<T> requiredType) {return applicationContext.getBean(requiredType);}public static <T> T getBean(String name, Class<T> requiredType) {return applicationContext.getBean(name, requiredType);}public static boolean containsBean(String name) {return applicationContext.containsBean(name);}public static boolean isSingleton(String name) {return applicationContext.isSingleton(name);}public static Class<? extends Object> getType(String name) {return applicationContext.getType(name);}
}
InitializingBean
InitializingBean接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是繼承該接口的類,在初始化bean的時候都會執行該方法。
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {@Overridepublic void afterPropertiesSet() {}
}
BeanFactoryAware
beanFactory讓你可以不依賴注入方式,隨意的讀取IOC容器里面的對象,不過beanFactory本身還是要注入的。
public class BeanFactorys implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public void init() {Object service = this.beanFactory.getBean("service");}
}
ImportBeanDefinitionRegistrar
作用:目的是實現bean的動態注入。
實現這個接口的類可以在使用@Configuration的地方引入,然后實現動態的bean注入到spring容器,這個是在@Bean注解定義bean 后動態的注入bean。
AutoConfigurationPackages
作用是將添加該注解的類所在的package 作為自動配置package進行管理。
可以通過AutoConfigurationPackages工具類獲取自動配置package列表。
FactoryBean
MetadataReader
https://blog.csdn.net/f641385712/article/details/88765470
BeanPostProcessor
**用于修改新實例化 Bean 對象的擴展點,**BeanPostProcessor 是在 Bean 對象實例化之后修改 Bean 對象,也可以替換 Bean 對象。
BeanFactoryPostProcess
允許自定義修改 BeanDefinition 屬性信息
public interface BeanFactoryPostProcessor {/*** 在所有的 BeanDefinition 加載完成后,實例化 Bean 對象之前,提供修改 BeanDefinition 屬性的機制** @param beanFactory* @throws BeansException*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}