Spring注解@DependsOn解析
介紹
今天要分享得是Spring的@DependsOn注解,對于@DependsOn,我們從它的名稱里面就能看出意思是“依賴于”,那么在Spring中,它的作用就是解決Bean的創(chuàng)建依賴,比如某個Bean在創(chuàng)建的時候依賴另外一個bean,所以需要另外一個bean先創(chuàng)建,然后再創(chuàng)建自己。
注解詳情
@DependsOn注解可以標注在類上和方法上面,只有一個屬性value,它是一個數(shù)組,表示依賴的bean名稱的數(shù)組,可以指定一個或者多個。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
String[] value() default {};使用
如下,在DependsOnBeanA上標注了@DependsOn注解,那么DependsOnBeanA需要在Bean dependsOnBeanB創(chuàng)建完成之后才能創(chuàng)建自己,這里value的值為bean的名稱,如果沒有對bean設置名稱,那么就為首字母為小寫的類名。
@Component
@DependsOn(value = {"dependsOnBeanB"})
public class DependsOnBeanA {
}源碼解析
spring掃描到所有的標有@Component(@Service,@Repository等注解本質(zhì)就是@Component)的類和標有@Bean的方法后,會進行處理,這里,它會判斷是否標注有@DependsOn,如果標注有,則會設置BeanDefinition的dependsOn,設置其依賴的bean,如下在AnnotationConfigUtils注解工具類中源碼如下。
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
//省略若干代碼
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
}上面是在注冊bean元數(shù)據(jù)階段,注冊元數(shù)據(jù)階段只是組裝好bean之間的依賴,然后在真正創(chuàng)建bean的時候,才會進行判斷,如下在AbstractBeanFactory類中的doGetBean中,會從RootBeanDefinition中取出dependsOn的值,不為空則進行bean的創(chuàng)建,創(chuàng)建bean的過程和其他bean的創(chuàng)建過程也是一樣的。
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
}從上面可以看出,其實還是比較簡單,主要就是判斷是否有依賴的bean,如果有就先創(chuàng)建依賴的bean,沒有的話就往下執(zhí)行。
總結(jié)
上面我們對@DependsOn作了簡單的介紹,對其的使用方法進行簡單示例,也對核心源碼進行分析,還是比較簡單,他們都是bean創(chuàng)建過程中的一些增強,spring的創(chuàng)建過程還是比較簡單,但是就是因為它的功能點比較多,所以在創(chuàng)建過程中會有各種擴展,各種判斷,所以就會變得很復雜,不過它的主線還是比較清晰的,在進行分析的時候,可以先從主線進行分析,然后再慢慢去看主線分出去的邏輯。
到此這篇關(guān)于Spring注解@DependsOn解析的文章就介紹到這了,更多相關(guān)Spring注解@DependsOn內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java核心編程之文件過濾類FileFilter和FilenameFilter
這篇文章主要為大家詳細介紹了java文件過濾類FileFilter和FilenameFilter,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
springboot實現(xiàn)敏感字段加密存儲解密顯示功能
這篇文章主要介紹了springboot實現(xiàn)敏感字段加密存儲,解密顯示,通過mybatis,自定義注解+AOP切面,Base64加解密方式實現(xiàn)功能,本文通過代碼實現(xiàn)給大家介紹的非常詳細,需要的朋友可以參考下2022-02-02
SpringBoot配置shiro安全框架的實現(xiàn)
這篇文章主要介紹了SpringBoot配置shiro安全框架的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04

