Maison  >  Article  >  Java  >  Exemples pour expliquer l'implémentation d'AOP dans le framework Spring de Java

Exemples pour expliquer l'implémentation d'AOP dans le framework Spring de Java

高洛峰
高洛峰original
2017-01-23 10:41:461285parcourir

Introduction
La programmation orientée aspect (AOP) offre un autre angle pour réfléchir à la structure du programme. De cette manière, elle compense les lacunes de la programmation orientée objet (POO). En plus des cours, AOP propose des aspects. Les aspects modularisent les préoccupations, telles que la gestion des transactions sur plusieurs types et objets. (Ces préoccupations sont souvent qualifiées de préoccupations transversales.)

Un élément clé de Spring est le cadre AOP. Néanmoins, le conteneur Spring IoC ne repose pas sur AOP, ce qui signifie que vous êtes libre de choisir d'utiliser ou non AOP. AOP fournit des solutions middleware puissantes, ce qui rend le conteneur Spring IoC plus complet.

Spring 2.0 AOP :

Spring 2.0 introduit un moyen plus simple et plus puissant de personnaliser les aspects. Les utilisateurs peuvent choisir d'utiliser une approche basée sur un schéma ou d'utiliser l'annotation @AspectJ. Pour les nouvelles applications, nous recommandons aux utilisateurs d'utiliser le style @AspectJ si elles sont développées avec Java 5, sinon ils peuvent utiliser le style basé sur des modèles. Les deux styles prennent entièrement en charge les types de conseils et le langage pointcut d'AspectJ, bien qu'ils utilisent toujours Spring AOP pour le tissage.

Ce chapitre traite principalement de la prise en charge par Spring 2.0 de l'AOP basé sur des modèles et basé sur @AspectJ. Spring 2.0 conserve entièrement la compatibilité descendante avec Spring 1.2. Le chapitre suivant discutera de la prise en charge AOP sous-jacente fournie par l'API Spring 1.2.

AOP utilisé au Spring :

Fournit des services d'entreprise déclaratifs, spécifiquement pour remplacer les services déclaratifs des EJB. Le service le plus important est la gestion déclarative des transactions, qui repose sur l'abstraction des transactions de Spring.

Permet aux utilisateurs d'implémenter des aspects personnalisés et d'utiliser l'AOP pour améliorer l'utilisation de la POO.

Exemples
Nous utilisons souvent les types suivants
1 AOP basé sur un proxy
2 Aspects d'objet Java purs et simples
3. Aspects aspcet sous forme d'injection
Appliquons-les un par un
Écrivons d'abord quelques cours de base.
Classe d'interface :

/** 
 * 定义一个接口 
 */
public interface Sleepable { 
  
  /** 
   * 睡觉方法 
   */
  void sleep(); 
}
Classe d'implémentation :


/**
 * 本人实现睡觉接口
 */
public class ChenLliNa implements Sleepable {
  
  @Override
  public void sleep() {
    // TODO Auto-generated method stub
    System.out.println("乖,该睡觉了!");
  }
}
Classe d'amélioration :

/**
 * 定义一个睡眠的增强 同时实现前置 和后置
 */
public class SleepHelper implements MethodBeforeAdvice, AfterReturningAdvice {
  
  @Override
  public void afterReturning(Object returnValue, Method method,
      Object[] args, Object target) throws Throwable {
     System.out.println("睡觉前要敷面膜");
  }
  
  @Override
  public void before(Method method, Object[] args, Object target)
      throws Throwable {
    System.out.println("睡觉后要做美梦");
  }
  
}


1. AOP basé sur un proxy

<!-- 创建一个增强 advice -->
  <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper"/>
  
  <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>
  <!-- 定义切点  匹配所有的sleep方法-->
  <bean id ="sleepPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
      <property name="pattern" value=".*sleep"></property>
  </bean>
    
  <!-- 切面  增强+切点结合 -->
  <bean id="sleepHelperAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
     <property name="advice" ref="sleepHelper"/>
     <property name="pointcut" ref="sleepPointcut"/>
  </bean>
    
  <!-- 定义代理对象 -->
  <bean id="linaProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
      <property name="target" ref="lina"/>
      <property name="interceptorNames" value="sleepHelperAdvisor"/>
      <!-- <property name="proxyInterfaces" value="com.tgb.springaop.service.Sleepable"/> -->
  </bean>
Par exemple, dans le fichier de configuration :

l'attribut pattern spécifie une expression régulière, qui correspond à toutes les méthodes de veille
Utilisez org.springframework.aop.support . Le but de DefaultPointcutAdvisor est de combiner des points de coupe et des améliorations pour former un aspect complet
Après la configuration finale, un objet proxy final est généré via org.springframework.aop.framework.ProxyFactoryBean.

2. Aspect objet Java pur et simple
Qu'entendez-vous par aspect objet Java pur et simple A mon avis, par rapport à la première configuration, il n'y a pas besoin d'utiliser un proxy, mais via ? spring. Le mécanisme interne scanne automatiquement. A ce moment, notre fichier de configuration doit être modifié comme suit :

<!-- 创建一个增强 advice -->
<bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper"/>
<!-- 目标类 -->
<bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>
  
<!-- 配置切点和通知-->
<bean id ="sleepAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
   <property name="advice" ref="sleepHelper"></property>
   <property name="pattern" value=".*sleep"/>
</bean>
  
<!-- 自动代理配置 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
Est-ce beaucoup plus simple que le premier Il n'y a pas besoin de configurer le proxy ? .


3. Formulaire d'annotation @Aspect
D'après notre expérience, nous savons que le formulaire d'annotation est plus simple que le fichier de configuration. À ce stade, vous devez annoter la méthode ou la classe existante :
.

/**
 * 通过注解的方式 添加增强
 */
@Aspect
@Component
public class SleepHelper03 {  
    
  /*@Pointcut("execution(* com.tgb.springaop.service.impl..*(..))")*/
  @Pointcut("execution(* *.sleep(..))")
  public void sleeppoint(){}
    
  @Before("sleeppoint()")
  public void beforeSleep(){
    System.out.println("睡觉前要敷面膜");
  }
    
  @AfterReturning("sleeppoint()")
  public void afterSleep(){
    System.out.println("睡觉后要做美梦");
  }
Dans le fichier de configuration, écrivez simplement :


<!--扫描包 -->
   <context:component-scan base-package="com.tgb" annotation-config="true"/> 
   <!-- ASPECTJ注解 -->
   <aop:aspectj-autoproxy proxy-target-class="true" /> 
     
   <!-- 目标类 -->
   <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>
4. Forme d'injection de l'aspect Aspcet

Personnellement, je pense que c'est le plus simple et le plus couramment utilisé, est également le plus flexible. Le fichier de configuration est le suivant :

<!-- 目标类 -->
  <bean id="lina" class="com.tgb.springaop.service.impl.ChenLliNa"/>
  <bean id ="sleepHelper" class="com.tgb.springaop.aspect.SleepHelper02"/>
    
  <aop:config>
    <aop:aspect ref="sleepHelper">
       <aop:before method="beforeSleep" pointcut="execution(* *.sleep(..))"/>
       <aop:after method="afterSleep" pointcut="execution(* *.sleep(..))"/>
    </aop:aspect>
  </aop:config>
La classe SleepHelper02 mentionnée dans le fichier de configuration est la suivante :

/**
 * 通过注解的方式 添加增强
 */
  
public class SleepHelper02 {
  public void beforeSleep(){
    System.out.println("睡觉前要敷面膜");
  }
  public void afterSleep(){
    System.out.println("睡觉后要做美梦");
  }
}


Doesn Est-ce que tout se ressemble ? C'est simple. Est-ce que tout le monde utilisera Spring Aop maintenant ? !


Concernant la façon d'appeler, voici plusieurs cours tests que vous pouvez consulter, ils sont fondamentalement les mêmes :

/**
 * 配置文件 spring_aop.xml 通过代理
 */
@Test
public void test(){
  ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop.xml");
    
  Sleepable sleeper =(Sleepable) ct.getBean("linaProxy");
    
  sleeper.sleep();
}
  
/**
 * 配置文件 spring_aop_01.xml  简答的java对象
 */
@Test
public void test01(){
  ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_01.xml");
    
  Sleepable sleeper = (Sleepable)ct.getBean("lina");
    
  sleeper.sleep();
}
  
/**
 * 配置文件 spring_aop_03.xml 通过aspect注解
 */
@Test
public void test03(){
  ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_03.xml");
    
    Sleepable sleeper = (Sleepable)ct.getBean("lina");
    
  sleeper.sleep();
}
/**
 * 配置文件 spring_aop_02.xml 通过apsect配置文件
 * @author 陈丽娜
 * @version 2015年5月31日上午10:09:37
 */
@Test
public void test02(){
  ApplicationContext ct = new ClassPathXmlApplicationContext("spring_aop_02.xml");
    
  Sleepable sleeper = (Sleepable)ct.getBean("lina");
    
  sleeper.sleep();
}


.

Il ressort des classes de test que quelle que soit la manière dont aop est implémenté, il n'y a aucune différence dans leur utilisation. Les résultats de ces classes de test sont les mêmes :

<.>Exemples pour expliquer limplémentation dAOP dans le framework Spring de JavaPour plus d'exemples expliquant l'implémentation d'AOP dans le framework Java Spring, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn