Principe du cache à trois niveaux du haricot printanier

Lorsque nous utilisons le framework Spring, nous rencontrons généralement des problèmes tels que des dépendances circulaires et des proxys AOP. Afin de résoudre ces problèmes, Spring introduit un mécanisme de cache à trois niveaux,
à savoir singletonObjects, earlySingletonObjects et singletonFactories trois caches. Cet article présentera en détail le principe et la fonction du cache à trois niveaux de Spring.

1. Le rôle du cache de troisième niveau de Spring

L'instanciation de bean et l'injection de dépendances sont des étapes très importantes dans le framework Spring. Dans ce processus, la dépendance circulaire et le proxy AOP sont deux problèmes relativement courants, et le mécanisme de cache à trois niveaux est conçu pour résoudre ces problèmes.
Plus précisément, les fonctions du cache à trois niveaux de Spring sont les suivantes :

Résolution des problèmes de dépendance circulaire : des problèmes de dépendance circulaire peuvent survenir lorsque la création d'un bean dépend de la création d'autres beans. Le mécanisme de mise en cache à trois niveaux de Spring peut résoudre les problèmes de dépendance circulaire au moyen d'objets proxy.

Assurer le mode singleton : Spring utilise le mode singleton pour gérer les beans par défaut, c'est-à-dire que le même bean n'est créé qu'une seule fois dans tout le cycle de vie de l'application. Le mécanisme de cache à trois niveaux peut garantir la bonne implémentation du mode singleton.

Améliorer les performances de Spring : l'utilisation de la mise en cache peut améliorer les performances de Spring, car la mise en cache peut éviter la surcharge liée à la création répétée d'instances de Bean.

Résoudre le problème de conflit entre l'objet proxy AOP et le nom de l'objet cible : lors de l'utilisation d'AOP, si l'objet cible et l'objet proxy sont mis en cache dans le cache singletonObjects, il peut y avoir un problème du fait que les deux objets portent le même nom, ce qui peut entraîner certains problèmes étranges surviennent, comme ne pas pouvoir injecter le bon objet. Par conséquent, Spring a introduit le cache singletonFactories pour résoudre ce problème.

2. Principe de mise en œuvre du cache à trois niveaux Spring

Dans Spring, le processus de création de bean peut être divisé en plusieurs étapes :
Parse BeanDefinition : lit les fichiers de configuration ou les annotations, etc., et analyse BeanDefinition en objets.
Créez une instance de bean : selon les informations contenues dans la définition de bean, créez une instance de bean et effectuez des opérations telles que l'injection et l'initialisation d'attributs.
Mettez l'instance de Bean dans le cache : placez l'instance de Bean créée dans le cache de Spring pour une utilisation ultérieure.
Dans ce processus, le mécanisme de mise en cache à trois niveaux de Spring joue un rôle important. Introduisons respectivement la fonction et le principe de mise en œuvre du cache à trois niveaux.
2.1 Cache singletonObjects
Le cache singletonObjects est le cache le plus couramment utilisé dans Spring et est utilisé pour stocker les instances Bean créées. Ce cache est un objet de type ConcurrentHashMap, qui a le nom du bean comme clé et l'instance du bean comme valeur.
Lors de l'utilisation du cache singletonObjects
, Spring essaiera d'abord d'obtenir l'instance Bean à partir du cache. Si l'instance de Bean correspondante n'existe pas dans le cache, l'opération de création d'une instance de Bean se poursuivra. Lors du processus de création d'une instance de bean, s'il s'avère que le bean actuel a été créé, il obtiendra l'instance de bean à partir du cache singletonObjects et la renverra.
Par défaut, la stratégie de stockage pour le cache singletonObjects est "exposition précoce". C'est-à-dire que lorsque l'instance de Bean est créée, elle sera immédiatement placée dans le cache singletonObjects. Cela peut garantir que la référence à l'instance peut être obtenue lors de la création de l'instance du bean, évitant ainsi le problème de la dépendance circulaire.
2.2 cache earlySingletonObjects
Le cache earlySingletonObjects est un cache rarement utilisé dans Spring. Son rôle est de stocker les instances de Bean "d'exposition précoce", c'est-à-dire les instances de Bean qui n'ont pas encore terminé l'injection de dépendance lorsque l'instance de Bean est créée.
Lors du processus de création d'une instance de bean, s'il s'avère que le bean dépend d'un autre bean qui n'a pas encore été créé, l'instance actuelle du bean sera placée dans le cache earlySingletonObjects. Une fois l'instance Bean dépendante créée, Spring effectuera une injection de dépendance sur l'instance Bean dans le cache earlySingletonObjects et la déplacera vers le cache singletonObjects.
2.3 Cache singletonFactories
Le cache singletonFactories est un cache spécialement conçu dans Spring pour résoudre le conflit de nom entre l'objet proxy AOP et l'objet cible. Lors de l'utilisation d'AOP, si l'objet cible et l'objet proxy sont tous deux mis en cache dans le cache singletonObjects, il peut y avoir un problème que les deux objets portent le même nom, ce qui peut entraîner des problèmes étranges, tels que l'impossibilité d'injecter l'objet correct .
Pour résoudre ce problème, Spring introduit le cache singletonFactories. Lors de la création d'un objet proxy, Spring crée d'abord un objet ObjectFactory et le place dans le cache singletonFactories. Lorsque l'objet proxy doit être utilisé, Spring appellera la méthode getObject() d'ObjectFactory pour créer l'objet proxy et le placer dans le cache singletonObjects.

3. Exemple d'utilisation du cache de troisième niveau

Afin de mieux comprendre le mécanisme de mise en cache à trois niveaux de Spring, examinons un exemple simple.
Supposons que nous ayons un bean nommé User qui dépend d'un autre bean nommé Role. À ce stade, le processus de création de Spring's Bean peut être divisé en plusieurs étapes :
analysez la définition de Bean de l'utilisateur et du rôle, et résolvez-la en objets.
Créez une instance de bean de rôle et placez-la dans le cache singletonObjects.
Créez une instance de bean utilisateur, découvrez qu'elle dépend du bean rôle et placez l'instance utilisateur dans le cache earlySingletonObjects.
Créez un objet proxy de l'instance du bean de rôle et placez l'objet proxy
dans le cache singletonObjects.
Injectez l'instance du bean rôle dans l'instance du bean utilisateur.
Déplacez l'instance User du cache earlySingletonObjects vers le cache singletonObjects.
Dans ce processus, le rôle du cache à trois niveaux peut être résumé comme suit :
Le cache singletonObjects est utilisé pour stocker les instances de Bean qui ont été créées et ont été injectées avec des dépendances.
Le cache earlySingletonObjects est utilisé pour stocker les instances de Bean qui ont été créées mais dont les dépendances n'ont pas encore été injectées.
Le cache singletonFactories est utilisé pour stocker l'objet fabrique de proxy lorsque le nom de l'objet proxy AOP et de l'objet cible sont identiques.
L'exemple de code pour utiliser le cache de troisième niveau est le suivant :

@Component
public class User {
    
    
 
    @Autowired
    private Role role;



    // 省略其他代码
}
}



@Component
public class Role {
    
    



    // 省略其他代码
}
}



@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
    
    



    @Bean
    public Role role() {
    
    
 
        return new Role();
 
    }



    @Bean
    public User user() {
    
    
 
        return new User();
 
    }



    @Bean
    public RoleInterceptor roleInterceptor() {
    
    
 
        return new RoleInterceptor();
 
    }



    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    
    
 
        return new DefaultAdvisorAutoProxyCreator();
 
    }



    @Bean
    public ProxyFactoryBean roleProxy() {
    
    
 
        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
 
        proxyFactoryBean.setTarget(role());
 
        proxyFactoryBean.addAdvice(roleInterceptor());
 
        return proxyFactoryBean;
 
    }
}
}



public class RoleInterceptor implements MethodInterceptor {
    
    
 
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
    
    
 
        System.out.println("before");
 
        Object result = invocation.proceed();
 
        System.out.println("after");
 
        return result;
 
    }
}
}



public class Main {
    
    
 
    public static void main(String[] args) {
    
    
 
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
 
        User user = context.getBean(User.class);
 
    }
}
}

Dans le code ci-dessus, nous avons créé un User Bean qui dépend du Role Bean. Nous avons également créé un RoleInterceptor en tant qu'intercepteur AOP du Role Bean, et un objet proxy du Role Bean.
Dans cet exemple, si nous supprimons un certain niveau du cache de troisième niveau, cela peut entraîner l'échec de la création du bean ou des problèmes étranges peuvent survenir. Par exemple, s'il n'y a pas de cache earlySingletonObjects, il peut y avoir un problème de dépendance circulaire,
résultant dans l'échec de la création de Bean.
S'il n'y a pas de cache singletonFactories, il peut y avoir des problèmes avec deux objets portant le même nom, entraînant l'injection du mauvais objet ou l'objet non injecté.
Par conséquent, le mécanisme de mise en cache à trois niveaux de Spring peut garantir l'exactitude de la création de Bean et de l'injection de dépendances, et peut également éviter efficacement certains problèmes étranges.

Supongo que te gusta

Origin blog.csdn.net/weixin_43866043/article/details/130222794
Recomendado
Clasificación