>  기사  >  Java  >  Java의 Spring 프레임워크에서 AOP 구현을 설명하는 예

Java의 Spring 프레임워크에서 AOP 구현을 설명하는 예

高洛峰
高洛峰원래의
2017-01-23 10:41:461308검색

소개
관점 지향 프로그래밍(AOP)은 프로그램 구조에 대해 생각할 수 있는 또 다른 각도를 제공합니다. 이러한 방식으로 객체 지향 프로그래밍(OOP)의 단점을 보완합니다. 클래스 외에도 AOP는 측면을 제공합니다. Aspect는 여러 유형 및 개체에 대한 트랜잭션 관리와 같은 문제를 모듈화합니다. (이러한 문제를 크로스커팅 문제라고도 합니다.)

Spring의 핵심 구성 요소는 AOP 프레임워크입니다. 그럼에도 불구하고 Spring IoC 컨테이너는 AOP에 의존하지 않습니다. 즉, AOP 사용 여부를 자유롭게 선택할 수 있습니다. AOP는 Spring IoC 컨테이너를 더욱 완벽하게 만드는 강력한 미들웨어 솔루션을 제공합니다.

Spring 2.0 AOP:

Spring 2.0에는 측면을 사용자 정의하는 더 간단하고 강력한 방법이 도입되었습니다. 사용자는 스키마 기반 접근 방식을 사용하거나 @AspectJ 주석을 사용할 수 있습니다. 새로운 애플리케이션의 경우 Java 5를 사용하여 개발된 경우 @AspectJ 스타일을 사용하는 것이 좋습니다. 그렇지 않으면 패턴 기반 스타일을 사용할 수 있습니다. 두 스타일 모두 어드바이스 유형과 AspectJ의 포인트컷 언어를 완벽하게 지원하지만 위빙에는 여전히 Spring AOP를 사용합니다.

이 장에서는 패턴 기반 및 @AspectJ 기반 AOP에 대한 Spring 2.0의 지원을 주로 논의합니다. Spring 2.0은 Spring 1.2와의 하위 호환성을 완전히 유지합니다. 다음 장에서는 Spring 1.2 API가 제공하는 기본 AOP 지원에 대해 설명합니다.

Spring에 사용되는 AOP:

특히 EJB 선언 서비스를 대체하기 위해 선언적 엔터프라이즈 서비스를 제공합니다. 가장 중요한 서비스는 Spring의 트랜잭션 추상화를 기반으로 구축된 선언적 트랜잭션 관리입니다.

사용자가 맞춤형 측면을 구현하고 AOP를 사용하여 OOP 활용도를 향상시킬 수 있습니다.


다음과 같은 것을 자주 사용합니다
1. Proxy 기반 AOP
2. 순수하고 단순한 Java 객체 측면
3. @Aspect 주석 형식
4. 주입 형태의 Aspce 측면
하나씩 적용해 보겠습니다
먼저 몇 가지 기본 클래스를 작성해 보겠습니다.
인터페이스 클래스:

/** 
 * 定义一个接口 
 */
public interface Sleepable { 
  
  /** 
   * 睡觉方法 
   */
  void sleep(); 
}

구현 클래스:

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

향상 클래스:

/**
 * 定义一个睡眠的增强 同时实现前置 和后置
 */
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

<!-- 创建一个增强 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>

예를 들어 구성 파일에서
pattern 속성은 모든 절전 방법과 일치하는 정규식을 지정합니다.
org.springframework.aop.support.DefaultPointcutAdvisor를 사용하는 목적은 다음과 같습니다. make pointcuts 개선과 결합하여 완전한 측면을 형성
최종 구성 후 org.springframework.aop.framework.ProxyFactoryBean을 통해 최종 프록시 객체가 생성됩니다.

2. 순수하고 단순한 Java 객체 측면
순수하고 단순한 Java 객체 측면이란 무엇을 의미하나요? 제 생각에는 첫 번째 구성에 비해 프록시를 사용할 필요가 없지만 이를 통해 spring.내부 메커니즘이 자동으로 스캔됩니다. 이때 구성 파일은 다음과 같이 수정되어야 합니다.

<!-- 创建一个增强 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"/>

처음보다 훨씬 간단하고 구성할 필요도 없습니다. 더 이상 프록시.

3. @Aspect 주석 형식
경험에 따르면 구성 파일보다 주석 형식이 더 간단하다는 것을 알고 있습니다. 이때 기존 메서드나 클래스에 주석을 달아야 합니다.

/**
 * 通过注解的方式 添加增强
 */
@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("睡觉后要做美梦");
  }

구성 파일에 다음과 같이 작성하세요.

<!--扫描包 -->
   <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. Aspce 측면의 주입 형태
개인적으로 이것이 가장 간단하고 일반적으로 사용되는 방식이라고 생각합니다. 또한 가장 유연합니다. 구성 파일은 다음과 같습니다.

<!-- 目标类 -->
  <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>

구성 파일에 언급된 SleepHelper02 클래스는 다음과 같습니다.

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


다 그렇지는 않습니다. 이렇게 간단해 보입니다. 모두가 Spring AOP를 사용할 것인가요? !

호출 방법에 관해서는 다음과 같은 몇 가지 테스트 클래스가 있습니다. 기본적으로 동일합니다.

/**
 * 配置文件 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();
}



테스트 클래스를 보면 AOP를 어떻게 구현하든 사용에 차이가 없음을 알 수 있습니다.

Java의 Spring 프레임워크에서 AOP 구현을 설명하는 예

Java의 Spring 프레임워크에서 AOP 구현을 설명하는 더 많은 예를 보려면 PHP 중국어 웹사이트에서 관련 기사를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.