Framework Spring "première connaissance de la programmation orientée aspect AOP"

Introduction à AOP

Dans l'industrie du logiciel, AOP est l'abréviation de Aspect Oriented Programming, ce qui signifie: programmation orientée aspect, une technologie de maintenance unifiée via la pré-compilation et des fonctions d'agent dynamique pendant l'exécution.

AOP est une continuation de la programmation orientée objet (Object Oriented Programming), un point chaud dans le développement logiciel, et un contenu important dans le framework Spring, et un paradigme dérivé de la programmation fonctionnelle.

Pourquoi AOP?

AOP résout le problème de l'extraction de code non métier.

  • Extraire le code non commercial répétitif et implanter dynamiquement le «code de section» dans la méthode métier pendant le fonctionnement.

  • Le mécanisme d' extraction horizontale remplace les codes répétitifs du système traditionnel d' héritage vertical .

L'utilisation d'AOP peut isoler les différentes parties de la logique métier, réduisant ainsi le couplage entre les différentes parties de la logique métier, améliorant la réutilisabilité du programme et améliorant en même temps l'efficacité du développement.

Spring AOP est implémenté en Java pur, ne nécessite pas de processus de compilation ni de chargeur de classe spéciaux, et intègre du code amélioré dans la classe cible via une méthode proxy pendant l'exécution .

AspectJ est un framework AOP basé sur le langage Java. À partir de Spring 2.0, Spring AOP introduit le support pour Aspect. AspectJ étend le langage Java et fournit un compilateur spécialisé pour fournir un tissage de code horizontal pendant la compilation.

Scénarios d'application AOP

Applications classiques: gestion des transactions, surveillance des performances, contrôles de sécurité, cache, logs .

En plus de réaliser des fonctions commerciales dans les systèmes d'entreprise, des fonctions non commerciales telles que l'interception des autorisations, la surveillance des performances et la gestion des transactions doivent également être mises en œuvre.

La pratique habituelle est que les codes non commerciaux sont entrecoupés de codes commerciaux, ce qui conduit au couplage de composants commerciaux et de composants non commerciaux.

La programmation orientée aspect AOP consiste à extraire ces codes non commerciaux dispersés dans divers codes de logique métier dans un module indépendant par découpe horizontale, de manière à réaliser le découplage des composants métier et des composants non métier.

Cohésion élevée : principe de responsabilité unique

Cependant, les journaux ne sont généralement pas écrits dans AOP et les journaux sont généralement codés en dur. Dans une méthode, différents emplacements peuvent utiliser des journaux différents. Cela nécessite des déclarations de jugement. De plus, les journaux sont très couramment utilisés, représentant généralement 4% des code global.

Terminologie AOP

Insérez la description de l'image ici

Cible (classe cible) : la classe qui doit être mandatée

  • Par exemple: UserSerrvice ci-dessus

Joinpoint (point de connexion) : le terme officiel (faisant référence aux points interceptés), c'est-à-dire les méthodes de la classe cible pouvant être connectées

  • Par exemple: toutes les méthodes de UserSerrvice

PointCut (point de coupure) : la déclaration officielle (que Joinpoints nous voulons intercepter), c'est-à-dire le point de connexion qui a été amélioré

  • Par exemple: addUser ()

Conseil (notification / amélioration) : code amélioré

  • Par exemple: avant, après

Tissage : fait référence au processus d'application de conseils améliorés à l'objet cible pour créer un nouvel objet proxy

Proxy : une fois qu'une classe est améliorée par AOP, une classe proxy de résultat est générée

Aspect (Aspect) : est une collection de PointCut et de conseils

  • Une ligne est un visage spécial

Exemple de code AOP

Expliquons la réalisation d'AOP à travers des exemples spécifiques ...

Par exemple, la méthode suivante:

//保存一个用户
public void add(User user) {
    
    
  	Session session = null;
  	Transaction trans = null;
  	try{
    
    
      	session = HibernateSessionFactoryUtils.getSession();  //关注点代码
      	trans = session.beginTransaction();  //关注点代码
      
      	session.save(user);  //『核心业务代码』
      
      	trans.commit; //关注点代码
    }catch (Exception e){
    
    
      	e.printStackTrace();
      	if(trans != null){
    
    
          	trans.rollback();  //关注点代码
        }
    }finally{
    
    
      	HibernateSessionFactoryUtils.closeSession(session);  //关注点代码
    }
}

Le code ci-dessus est en fait la ligne de code la plus centrale: enregistrez l'objet utilisateur dans la base de données

session.save(user);

Notre table de base de données est certainement plus qu'une table utilisateur. En plus de la méthode add (), les opérations sur la base de données incluent la suppression, la modification et la vérification.

Nous pouvons donc imaginer: chaque fois que vous exploitez la base de données, vous devez écrire du code comme "open transaction" et "close transaction".

Ce code est répétitif pour nous, nous voudrons donc " extraire " ce code .

Si nous utilisons simplement la pensée OOP (orientée objet) pour encapsuler du code non métier, notre effet final peut être comme ceci:

public class UserDao() {
    
    
  	AOP aop;
  	public void save() {
    
    
      	aop.begin();
      	System.out.println("DB:保存用户");
      	aop.close();
    }
}

Même s'il semble que le code soit très petit, nous trouverons qu'il ne s'agit que d'une encapsulation du code non commercial d'origine, mais la méthode finale update () / delete () aura également aop.begin();ce code en double.

Et notre objectif est d'éliminer complètement un tel code (non visible sur le clair), mais peut toujours atteindre la fonction d'origine, alors nous devons utiliser "proxy dynamique", via un proxy dynamique, écrire du code non commercial dans le "amélioré" Logiquement.

public class ProxyFactory {
    
    
  	//维护目标对象
  	private static Object target;
  	//维护关键点代码的类
  	private static AOP aop;
  
  	public static Object getProxyInstance(Object target_, AOP aop_) {
    
    
      	//目标对象和关键点代码的类都是通过外界传递进来
      	target = target_;
        aop = aop_;
      	
      	return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler(){
    
    
								@Override
              	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
    
    
                  	aop.begin();
                  	Object returnValue = method.invoke(target, args);
                  	aop.close();
                  
                  	return returnValue;
                }
            }
        );
    }
}

Après cela, nous pouvons utiliser "l'objet proxy" pour appeler la méthode, et enfin bloquer le "code dupliqué"

public class App {
    
    
  	public static void main(String[] args) {
    
    
      	ApplicationContext ac = new ClassPathXmlApplicationContext("dao/applicationContext.xml");
      	IUser iUser = (IUser)ac.getBean("proxy");
      	iUser.save();
    }
}

Ce qui précède est un agent de bricolage pour extraire du "code non commercial". Il existe de nombreux scénarios comme celui-ci, tels que le contrôle des autorisations, la vérification des paramètres, etc.

Spring AOP nous permet de ne pas écrire d'objets proxy manuellement, pour obtenir l'effet d'extraire du "code non commercial".

Voici le code implémenté à l'aide de Spring AOP:

@Component
@Aspect //指定为切面类
public class AOP{
    
    
  
  	//里面的值为切入点表达式
  	@Before("execution(* dao.*.*(..))")
  	public void begin() {
    
    
      	System.out.println("开始事务");
    }
  
  	@After("execution(* dao.*.*(..))")
  	public void close() {
    
    
      	System.out.println("关闭事务");
    }
}

parmi eux:

//接口(在dao包下)
public nterface IUser {
    
    
  	void save();
}
//实现类(在dao包下)
@Component
public class UserDao implements IUser {
    
    
  	@Override
  	public void save(){
    
    
      	System.out.println("DB:保存用户");
    }
}

tester:

public class APP {
    
    
  	public static void main(String[] args) {
    
    
      	ApplicationContext ac = new ClassPathXmlApplicationContext("dao/applicationContext.xml");
      
      	//这里得到的是代理对象
      	IUser iUser = (IUser)ac.getBean("userDao");
      	System.out.println(iUser.getClass());
      	iUser.save();
    }
}

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44471490/article/details/109190104
conseillé
Classement